java8 [method reference]

原文:method reference

lambda表达式通常用匿名方法。而有时候,lambda表达式做的仅仅是调用一个已经存在的方法,可以通过函数名调用该函数,即method reference。

以数组排序为例:

pubic class Person {
    public static int compareByAge(Person a, Person b) {
        return a.birthday.compareTo(b.birthday);
    }
}
Person[] personArray = ...
class PersonAgeComparator implements Comparator {
    ...
}

personArray排序

Arrays.sort(personArray, new PersonArayComparator());

该sort函数的签名是:
static void sort(T [] a, Comparator c)

functional interface

因为Comparator是一个函数接口(functional interface),因此可以用lambda替换:
Arrays.sort(personArray, (a,b) -> Person.compareByAge(a, b));

method reference

又可以通过函数名调用该函数,替换后的lambda:
Arrays.sort(personArray, Person::compareByAge);

两种已经存在的函数的lambda表达式,method reference和functional interface:
Person::compareByAge和(a,b)->Person.compareByAge(a,b)

四种Method references

类型 表达式
静态方法 FooClass::staticMethodName
特定对象的实例方法 fooObject::instanceMethodName
特定类型的任意对象的实例方法 FooClass::instanceMethodName
constructor FooClass::new

引用静态方法

Person::compareByAge

引用特定对象的实例方法

class ComparisonProvider {
 public int compareByName(Person a, Person b) {
     return a.getName().compareTo(b.getName());
}
ComparisonProvider obj = new ComparisonProvider();
Arrays.sort(rosterAsArray, obj::compareByName)   

method reference obj::compareByName调用obj对象的compareByName方法,JRE推断出它的参数类型。这个例子中是(Person, Person)

引用特定类型的任意对象的实例方法

String[] stringArray = {"A", "B", "C"};
Arrays.sort(stringArray, String::compareToIgnoreCase);

method reference String::compareToIgnoreCase等效的lambda表达式参数列表(String a, String b),其中a和b是任意的名字。method reference会调用方法a.compareToIgnoreCase(b)

Constructor

public static , DEST extends Collection> DEST transferElements(
    SOURCE sourceCollection, 
    Supplier collectionFactory) {
    DEST result = collectionFactory.get();
    for (T t : sourceCollection) {
        result.add(t);
    }
    return result;
}

functional interface Supplier包含一个方法getget方法没有参数并且返回一个对象,因此可以用lambda表达式调用函数transferElements:

Set rosterSetLambda = transferElements(roster, () -> {return new HashSet<>();});

也可以用一个constructor reference替代lambda的位置:

Set rosterSet = transferElements(roster, HashSet::new);

编译器推断出你想要创建一个HashSet元素的类型是Person,也可以指定类型为Person
transferElements(roster, HashSet::new);

关键词:已经存在的方法;lambda


你可能感兴趣的:(java,8)