方法参考

方法引用允许遵循兼容功能接口的预定义静态或实例方法作为参数而不是匿名 lambda 表达式传递。

假设我们有一个模型:

class Person {
    private final String name;
    private final String surname;

    public Person(String name, String surname){
        this.name = name;
        this.surname = surname;
    }

    public String getName(){ return name; }
    public String getSurname(){ return surname; }
}

List<Person> people = getSomePeople();

实例方法引用(对任意实例)

people.stream().map(Person::getName)

等价的 lambda:

people.stream().map(person -> person.getName())

在此示例中,正在传递对 Person 类型的实例方法 getName() 的方法引用。由于它已知是集合类型,因此将调用实例上的方法(稍后知道)。

实例方法引用(对特定实例)

people.forEach(System.out::println);

由于 System.outPrintStream 的一个实例,因此将对此特定实例的方法引用作为参数传递。

等价的 lambda:

people.forEach(person -> System.out.println(person));

静态方法参考

同样,对于转换流,我们可以应用对静态方法的引用:

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6);
numbers.stream().map(String::valueOf)

此示例传递对 String 类型的静态 valueOf() 方法的引用。因此,集合中的实例对象作为参数传递给 valueOf()

等价的 lambda:

 numbers.stream().map(num -> String.valueOf(num))

引用构造函数

List<String> strings = Arrays.asList("1", "2", "3");
strings.stream().map(Integer::new)

阅读将流的元素收集到集合中以查看如何收集要收集的元素。

这里使用 Integer 类型的单个 String 参数构造函数,在给定作为参数提供的字符串的情况下构造整数。在这种情况下,只要字符串表示数字,流就会映射到整数。等价的 lambda:

strings.stream().map(s -> new Integer(s));

备忘单

方法参考格式 等价的 Lambda
静态方法 TypeName::method (args) -> TypeName.method(args)
非静态方法(例如 * instance::method (args) -> instance.method(args)
非静态方法(无实例) TypeName::method (instance, args) -> instance.method(args)
构造函数 ** TypeName::new (args) -> new TypeName(args)
数组构造函数 TypeName[]::new (int size) -> new TypeName[size]

* instance 可以是任何评估为对实例的引用的表达式,例如 getInstance()::methodthis::method

** 如果 TypeName 是非静态内部类,则构造函数引用仅在外部类实例的范围内有效