龙盟编程博客 | 无障碍搜索 | 云盘搜索神器
快速搜索
主页 > 软件开发 > JAVA开发 >

Java函数式编程(九):Comparator(3)

时间:2014-09-27 03:12来源:网络整理 作者:网络 点击:
分享到:
复制代码 代码如下: ComparatorPerson compareAscending = (person1, person2) - person1.ageDifference(person2); ComparatorPerson compareDescending = compareAscending.reversed(); 我们先创建了一

复制代码 代码如下:

Comparator<Person> compareAscending =
(person1, person2) -> person1.ageDifference(person2);
Comparator<Person> compareDescending = compareAscending.reversed();

我们先创建了一个Comparator,compareAscending,来将人按年龄从小到大进行排序。为了反转比较顺序,而不是再写一次这个代码,我们只需要调用一下这个第一个Comparator的reversed()方法就可以获取第二个Comparator对象。在reversed()方法底层,它创建了一个比较器,来交换了比较的参数的顺序。这说明reversed也是一个高阶方法——它创建并返回了一个无副作用的函数。我们把这个两个比较器用到代码里。
复制代码 代码如下:

printPeople("Sorted in ascending order by age: ",
      people.stream()
    
    
.sorted(compareAscending)
    
    
.collect(toList())
);
printPeople("Sorted in descending order by age: ",
people.stream()
.sorted(compareDescending)
.collect(toList())
);

从代码中明显可以看到,Java8的这些新特性极大的减少了代码的冗余及复杂度,不过好处远不止这些,JDK里还有无限可能等着你去探索。

我们已经可以按年龄进行排序了,想按名字来排序的话也很简单。我们来按名字进行字典序排列,同样的,只需要改下lambda表达式里的逻辑就好了。

复制代码 代码如下:

printPeople("Sorted in ascending order by name: ",
people.stream()
.sorted((person1, person2) ->
person1.getName().compareTo(person2.getName()))
.collect(toList()));

输出的结果里会按名字的字典序进行排列。
复制代码 代码如下:

Sorted in ascending order by name:
Greg - 35
Jane - 21
John - 20
Sara - 21

现在为止,我们要么就按年龄排序,要么就按名字排序。我们可以让lambda表达式的逻辑更智能一些。比如我们可以同时按年龄和名字排序。

我们来选出列表中最年轻的人来。我们可以先按年龄从小到大排序然后选中结果中的第一个。不过其实用不着那样,Stream有一个min()方法可以实现这个。这个方法同样也接受一个Comparator,不过返回的是集合中最小的对象。我们来用下它。

复制代码 代码如下:

people.stream()
.min(Person::ageDifference)
.ifPresent(youngest -> System.out.println("Youngest: " + youngest));

调用min()方法的时候我们用了ageDifference这个方法引用。min()方法返回的是一个Optinal对象,因为列表可能为空并且里面可能不止一个年纪最小的人。接着我们通过Optinal的ifPrsend()方法获取到年纪最小的那个人,并打印出他的详细信息。来看下输出结果。
复制代码 代码如下:

Youngest: John - 20

输出年纪最大的同样也很简单。只要把这个方法引用传给一个max()方法就好了。

复制代码 代码如下:

people.stream()
.max(Person::ageDifference)
.ifPresent(eldest -> System.out.println("Eldest: " + eldest));

我们来看下最年长那位的名字和年龄。
复制代码 代码如下:

Eldest: Greg - 35

有了lambda表达式和方法引用之后,比较器的实现变得更简洁也更方便了。JDK也给Compararor类引入了不少便利的方法,使得我们可以更流畅的进行比较,下面我们将会看到。

多重比较和流式比较

我们来看下Comparator接口提供了哪些方便的新方法,并用它们来进行多个属性的比较。

精彩图集

赞助商链接