我们在设计lambda时的一个重要目标就是新增的语言特性和库特性能够无缝结合(designed to work together)。接下来,我们通过一个实际例子(按照姓对名字列表进行排序)来演示这一点:
比如说下面的代码:
List<Person> people = ...
Collections.sort(people, new Comparator<Person>() {
public int compare(Person x, Person y) {
return x.getLastName().compareTo(y.getLastName());
}
})
冗余代码实在太多了!
有了lambda表达式,我们可以去掉冗余的匿名类:
Collections.sort(people, (Person x, Person y) -> x.getLastName().compareTo(y.getLastName()));
尽管代码简洁了很多,但它的抽象程度依然很差:开发者仍然需要进行实际的比较操作(而且如果比较的值是原始类型那么情况会更糟),所以我们要借助Comparator里的comparing方法实现比较操作:
Collections.sort(people, Comparator.comparing((Person p) -> p.getLastName()));
在类型推导和静态导入的帮助下,我们可以进一步简化上面的代码:
Collections.sort(people, comparing(p -> p.getLastName()));
我们注意到这里的lambda表达式实际上是getLastName的代理(forwarder),于是我们可以用方法引用代替它:
Collections.sort(people, comparing(Person::getLastName));
最后,使用Collections.sort这样的辅助方法并不是一个好主意:它不但使代码变的冗余,也无法为实现List接口的数据结构提供特定(specialized)的高效实现,而且由于Collections.sort方法不属于List接口,用户在阅读List接口的文档时不会察觉在另外的Collections类中还有一个针对List接口的排序(sort())方法。
默认方法可以有效的解决这个问题,我们为List增加默认方法sort(),然后就可以这样调用:
people.sort(comparing(Person::getLastName));
此外,如果我们为Comparator接口增加一个默认方法reversed()(产生一个逆序比较器),我们就可以非常容易的在前面代码的基础上实现降序排序。
people.sort(comparing(Person::getLastName).reversed());
Java SE 8提供的新语言特性并不算多——lambda表达式,方法引用,默认方法和静态接口方法,以及范围更广的类型推导。但是把它们结合在一起之后,开发者可以编写出更加清晰简洁的代码,类库编写者可以编写更加强大易用的并行类库。
网友评论