Method References的种类
我觉得国内的盗链以及随意的盗文的确很严重。。。
有必要以后每次都写一下文章来源:blog.csdn.net/forevervip
这几天本想把Method Reference赶紧收尾然后写下一个Aggregate的说明,因为Aggregate是Lambda和Method Reference的混合载体,但是一直被一个问题困扰解释不明白,连泛型后来都重新看了一遍,最后想起JVM的一些底层理论才解决。后面写到Aggregate的时候再来讨论。
Method References的静态方法参照
public static int compareByAge(Person a, Person b) {
return a.birthday.compareTo(b.birthday);
}}
上一篇中,我们参照的方法本身就是一个static方法,所以static方法是可以参照的。
写法为: static的class : : 参照的static方法
Method References的实例方法参照
class ComparisonProvider {
public int compareByName(Person a, Person b) {
return a.getName().compareTo(b.getName());
}
public int compareByAge(Person a, Person b) {
return a.getBirthday().compareTo(b.getBirthday());
}
}
ComparisonProvider myComparisonProvider = new ComparisonProvider();
Arrays.sort(rosterAsArray, myComparisonProvider::compareByName);
这里,我们参照的是一个类ComparisonProvider 的实例的myComparisonProvider的compareByName的方法,那么我们首先需要实例化这个类,然后进行方法参照。
写法为: 实例化的名称: : 参照的方法
Method References的类型参照
String[] stringArray = { "Barbara", "James", "Mary", "John",
"Patricia", "Robert", "Michael", "Linda" };
Arrays.sort(stringArray, String::compareToIgnoreCase);
例子中,String::compareToIgnoreCase相当于调用的是(a,b) -> a.compareToIgnoreCase(b) 的Lambda表达式,这是两个String类型再进行比较的方式,这里的String : : 代表类型。
写法为: 类型名称: : 参照的方法
Method References的构造方法参照
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;
}
我们先定义以上的一个方法。
其中,有一个Supplier的class,
这个Supplier是JDK8中提供的一个函数式接口:
/*
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package java.util.function;
/**
* Represents a supplier of results.
*
* <p>There is no requirement that a new or distinct result be returned each
* time the supplier is invoked.
*
* <p>This is a <a href="package-summary.html">functional interface</a>
* whose functional method is {@link #get()}.
*
* @param <T> the type of results supplied by this supplier
*
* @since 1.8
*/
@FunctionalInterface
public interface Supplier<T> {
/**
* Gets a result.
*
* @return a result
*/
T get();
}
写了这么多废话,其实经过泛型的编译擦涂之后其实就是下面这么个类:
public interface Supplier {
Object get();
}
这个类作为函数式接口作用是为了返回一个任意被定义(指定)的泛型类型的实例。
假设我们在调用的时候希望定义一个HashSet,那么Lambda表达式可以写成:
Set<Person> rosterSetLambda =
transferElements(roster, () -> { return new HashSet<>(); });
这种情况下,方法参照可以写成下面这个样子:
Set<Person> rosterSet = transferElements(roster, HashSet::new);
这也是我们需要得到一个实例的时候的一般做法,定义一个Supplier的函数式接口,然后写Class : : new的方法参照。因为后面的Aggregate还要使用到这个方法,Supplier也被java自身的Aggregate的api所调用,所以还是比较重要的一个用法。
写法为: 类名称(构造方法名称): : new关键字
文章来源:blog.csdn.net/forevervip
つづく・・・