天天看點

java 8 排序_Java8的Lambda和排序

Java8的Lambda和排序

對數組和集合進行排序是Java 8 lambda令人驚奇的一個應用,我們可以實作一個Comparators來實作各種排序。看下面案例:

static class Person {

final String firstName;

final String lastName;

Person(String firstName, String lastName) {

this.firstName = firstName;

this.lastName = lastName;

}

@Override

public String toString() {

return "Person{" +

"firstName='" + firstName + '\'' +

", lastName='" + lastName + '\'' +

'}';

}

}

Person的資料有:

List people =

Arrays.asList(

new Person("Jane", "Henderson"),

new Person("Michael", "White"),

new Person("Henry", "Brighton"),

new Person("Hannah", "Plowman"),

new Person("William", "Henderson")

);

我們希望根據名字排序(last name),然後再根據姓(first name)排序。

在Java 7之前,我們通常是通過實作一個Comparator:

people.sort(new Comparator() {

@Override

public int compare(Person o1, Person o2) {

int result = o1.lastName.compareTo(o2.lastName);

if (result == 0)

result = o1.firstName.compareTo(o2.firstName);

return result;

}

});

people.forEach(System.out::println);

而在Java 8中,我們可以使用lambda替代匿名函數,如下:

Comparator c = (p, o) -> p.lastName.compareTo(o.lastName);

c = c.thenComparing((p, o) -> p.firstName.compareTo(o.firstName));

people.sort(c);

people.forEach(System.out::println);

在這裡,Lambda表達式(p, o) -> p.lastName.compareTo(o.lastName)替代之前的匿名函數new Comparator() {}

因為Java編譯器并不能推遲對Lambda表達式類型判斷,比如延遲到将comparator傳遞到sort()方法,是以使得我們進行鍊式Comparator書寫有點困難,比如我們想寫成如下:

XXX.thenComparing((p, o) -> p.lastName.compareTo(o.lastName))

.thenComparing((p, o) -> p.firstName.compareTo(o.firstName))

換句話說,類型判斷是從左到右,而不是從右到左,我們可以通過建立一個泛型來進行類型推斷:

class Utils {

static Comparator compare() {

return (e1, e2) -> 0;

}

}

通過上面的compare()方法,我們可以書寫流暢的comparator鍊:

people.sort(

Utils.compare()

.thenComparing((p, o) ->

p.lastName.compareTo(o.lastName))

.thenComparing((p, o) ->

p.firstName.compareTo(o.firstName))

);

people.forEach(System.out::println);

本文譯自Java8 Friday系列,源碼Gihub