Java 8 官方教程翻译——方法引用(method reference)
2014-12-26 14:43
543 查看
你可能会使用lambda表达式创建匿名方法。然而有时lambda表达式仅仅调用了一个已存在的方法。这种情况下,直接使用该方法名会显得更加简洁。方法引用正是用在此处;他们是有名方法的紧凑而又易读的lambda表达式。回顾在Lambda Expressions一节中讨论过的Person类:
对静态方法的引用Person::compareByAge就是一个静态方法引用对特定对象的实例方法的引用下面的实例,展示了对特定对象的实例方法的引用:
public class Person {
public enum Sex {
MALE, FEMALE
}
String name;
LocalDate birthday;
Sex gender;
String emailAddress;
public int getAge() {
// ...
}
public Calendar getBirthday() {
return birthday;
}
public static int compareByAge(Person a, Person b) {
return a.birthday.compareTo(b.birthday);
}}假设社交网络应用程序中的成员信息使用数组进行存储,现在你需要按成员年龄将数组排序。那么你可以使用如下代码:
Person[] rosterAsArray = roster.toArray(new Person[roster.size()]);
class PersonAgeComparator implements Comparator<Person> {
public int compare(Person a, Person b) {
return a.getBirthday().compareTo(b.getBirthday());
}
}Arrays.sort(rosterAsArray, new PersonAgeComparator());该sort方法的签名如下:
static <T> void sort(T[] a, Comparator<? super T> c)我们注意到Comparator接口是一个函数接口,因而可以使用lambda表达式取而代之,从而避免了需要定义一个实现Comparator的类并且对之实例化。
Arrays.sort(rosterAsArray,
(Person a, Person b) -> {
return a.getBirthday().compareTo(b.getBirthday());
}
);然而,按照年龄比较两个Person实例的方法已经存在于Person类中,因此可以直接在lambda表达式中调用:
Arrays.sort(rosterAsArray,
(a, b) -> Person.compareByAge(a, b)
);因为这个lambda表达式调用了一个已存在的方法,因而可以使用方法引用替换这个lambda表达式:
Arrays.sort(rosterAsArray, Person::compareByAge);方法引用Person::CompareByAge和lambda表达式(a, b) -> Person.compareByAge(a, b)在语意上是等价的。分别都具有以下的特征:形式参数列表与Comparator<Person>.campare相同,(Person, Person)方法体调用了Person.compareByAge方法。方法引用的类型共有四种方法引用:
Kind | Example |
对静态方法的引用 | ContainingClass::staticMethodName |
对特定对象的实例方法的引用 | containingObject::instanceMethodName |
对特定类型的任意对象的实例方法的引用 | ContainingType::methodName |
对构造方法的引用 | ClassName::new |
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);方法引用myComparisonProvider::compareByName调用了对象myComparisonProvider的方法compareByName。Java运行时推倒出了方法的类型参数,为(Person, Person)。对特定类型的任意对象的实例方法的引用请看下面的例子:
String[] stringArray = { "Barbara", "James", "Mary", "John",
"Patricia", "Robert", "Michael", "Linda" };
Arrays.sort(stringArray, String::compareToIgnoreCase);与该方法引用String::compareToIgnoreCase等价的Lambda表达式拥有形式参数列表(String a, String b),其中a和b可以是任意有意义的名字。该方法引用实际调用了方法a.compareToIgnoreCase(b)。对构造方法的引用引用构造方法只需要将静态方法引用中的方法名替换为new即可。下面的方法将元素从一个集合复制到另一集合。
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包含了一个get方法,不接收参数并返回一个对象。因而,你可以使用lambda表达式调用transferElements方法:
Set<Person> rosterSetLambda =
transferElements(roster, () -> { return new HashSet<>(); });进一步的,该lambda表达式可以使用构造函数引用替换:
Set<Person> rosterSet = transferElements(roster, HashSet::new);Java编译器推导出你需要创建一个包含Person元素的HashSet,因而你可以更明确的指定:
Set<Person> rosterSet = transferElements(roster, HashSet<Person>::new);
相关文章推荐
- java8方法引用(Method reference)
- Java 8 官方教程翻译——默认方法(default method)
- 智渔课堂官方免费教程八:Java基础之方法(函数)
- Can be replaced with method reference less 可以用代码更少的方法引用代替
- Java 3D API官方教程[翻译四]
- Java 3D API官方教程[翻译三]
- Java 8 官方教程翻译——Lambda表达式
- 【Netty官方文档翻译】引用计数对象(reference counted objects)
- Java中方法调用参数传递的方式是传值,尽管传的是引用的值而不是对象的值。(Does Java pass by reference or pass by value?)
- I学霸官方免费教程八:Java基础之方法(函数)
- Java 8 新特性-菜鸟教程 (2) -Java 8 方法引用
- Java 3D API官方教程[翻译一]
- Java 3D API官方教程[翻译五]
- Java 3D API官方教程[翻译二]
- 自适应变异引用(AWR)方法(an adaptive warped reference (AWR) method )
- spring3.2.1api文档(翻译官方英文版的方法),spring-framework-reference,spring-framework-3.2.1.RELEASE
- 【Netty官方文档翻译】引用计数对象(reference counted objects)
- 《Java: The Complete Reference》《Java 8 编程参考官方教程(第9版)》读书笔记
- java8学习教程之函数引用的使用方法
- Java 3D API官方教程[翻译一]