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<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
constructorFooClass::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


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值