java8 [method reference]

来源:互联网 发布:英雄联盟网络连接断开 编辑:程序博客网 时间:2024/05/21 19:10

原文: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<Person> {    ...}

personArray排序

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

该sort函数的签名是:
static <T> void sort(T [] a, Comparator<? super T> 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 <T, SOURCE extends Collection<T>, DEST extends Collection<T>> DEST transferElements(    SOURCE sourceCollection,     Supplier<DEST> collectionFactory) {    DEST result = collectionFactory.get();    for (T t : sourceCollection) {        result.add(t);    }    return result;}

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

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

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

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

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

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


原创粉丝点击