【有书共读】Java攻略 读书笔记02

lambda与方法引用

  • 如果说lambda表示式本质上是将方法作为对象进行处理,那么方法引用就是将现有方法作为lambda表达式进行处理
  • 我们首先来看下面这个例子
import java.util.function.Consumer; import java.util.stream.Stream; public class Test01 {
    public static void main(String[] args) {
        // 使用lambda表达式,将流的所有元素打印到标准输出         Stream.of(3, 1, 4, 1, 5, 9).forEach(x -> System.out.println(x));

        // 使用方法引用的方式,将流的所有元素打印到标准输出         // 双冒号表示法在system.out实例上提供了对println方法的引用,属于PrintStream类型的引用。方法引用的末尾无需括号         Stream.of(3, 1, 4, 1, 5, 9).forEach(System.out::println);

        // 将方法引用赋给函数式接口,将流的所有元素打印到标准输出         Consumer<Integer> printer = System.out::println;
        Stream.of(3, 1, 4, 1, 5, 9).forEach(printer);

        // 在静态方法中使用方法引用         Stream.generate(Math::random)// 静态方法                 .limit(10).forEach(System.out::println);// 实例方法     }
}
  • 与lambda语法相比,方法引用具有以下2个优点,使得代码更易于阅读
    • 首先,方法引用往往更短
    • 其次,方法引用通常包括含有该方法的类的名称

语法

方法引用包括以下三种方式

  • object::instanceMethod
    • 引用特定对象的实例方法,如System.out::println
  • Class::staticMethod
    • 引用静态方法,如:Math::max
  • Class::instanceMethod
    • 调用特定类型的任意对象的实例方法,如String::length

lambda表达式和方法引用在任何情况下都不能脱离上下文存在,有时候为避免歧义,经常在方法引用的左侧使用this或super

  • 以对象引用为例,上下文提供了方法的参数;对于System.out::println,等效的lambda表达式为:

    • //相当于System.out::println
    • x -> System.out.println(x);
    • 上下文提供了x的值,它被用作方法的参数
  • 静态方法max与之类似

    • //相当于Math::max
    • (x,y)->Math.max(x,y)
    • 此时,需要上下文提供两个参数,lambda表达式返回较大的数
  • 通过类名调用实例方法,等效的lambda表达式为:

    • //相当于String::length
    • x -> x.length()
    • 此时上下文提供x的值,用作方法的目标而非参数

如果通过类名引用一个传入多个参数的方法,则上下文提供的第一个元素将作为方法的目标,其他元素作为方法的参数

import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; /**
 * Stream接口定义的sorted方法传入Comparator<T>作为参数 其单一抽象方法为int compare(String other)
 * sorted方法将每对字符串提供给比较器,并提供返回整数的符号对它们进行排序 */ public class Test02 {
    public static void main(String[] args) {
        List<String> strings = Arrays.asList("this", "is", "a", "list", "of", "strings");

        List<String> sorted1 = strings.stream()
                .sorted((s1, s2) -> s1.compareTo(s2))// 调用第一个参数s1compareTo方法,并使用第二个元素s2作为该方法的参数                 .collect(Collectors.toList());

        List<String> sorted2 = strings.stream()
                .sorted(String::compareTo)
                .collect(Collectors.toList());
    }
}
  • 在流处理中,如果需要处理一系列的输入,则会频繁的使用方法引用中的类名来访问实例方法,如下例子
import java.util.stream.Stream; /**
 * 程序调用length方法并将每个字符串转换成一个整数打印出来 */ public class Test03 {
    public static void main(String[] args) {
        Stream.of("this", "is", "a", "list", "of", "strings")
                .map(String::length)// 通过类名访问实例方法                 
                                .forEach(System.out::println);// 通过对象引用访问实例方法           //等效的lambda表示式         Stream.of("this", "is", "a", "list", "of", "strings")
                .map(s -> s.length())
                .forEach(x -> System.out.println(x));

    }
}

#Java##读书笔记##笔记#
全部评论

相关推荐

评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务