# Java8：Lambda表达式增强版Comparator和排序

1、概述

public class Human {

private String name;

private int age;

public Human() {

super ();

}

public Human( final String name, final int age) {

super ();

this .name = name;

this .age = age;

}

// standard getters and setters

}

2、不使用Lambda表达式的基本排序

new Comparator<Human>() {

@Override

public int compare(Human h1, Human h2) {

return h1.getName().compareTo(h2.getName());

}

}

@Test

public void givenPreLambda_whenSortingEntitiesByName_thenCorrectlySorted() {

List<Human> humans = Lists.newArrayList( new Human( "Sarah" , 10 ), new Human( "Jack" , 12 ));

Collections.sort(humans, new Comparator<Human>() {

@Override

public int compare(Human h1, Human h2) {

return h1.getName().compareTo(h2.getName());

}

});

Assert.assertThat(humans.get( 0 ), equalTo( new Human( "Jack" , 12 )));

}

3、使用Lambda表达式的基本排序

( final Human h1, final Human h2) -> h1.getName().compareTo(h2.getName());

@Test

public void whenSortingEntitiesByName_thenCorrectlySorted() {

List<Human> humans = Lists.newArrayList( new Human( "Sarah" , 10 ), new Human( "Jack" , 12 ));

humans.sort((Human h1, Human h2) -> h1.getName().compareTo(h2.getName()));

Assert.assertThat(humans.get( 0 ), equalTo( new Human( "Jack" , 12 )));

}

4、没有类型定义（ Type Definitions）的基本排序

(h1, h2) -> h1.getName().compareTo(h2.getName())

@Test

public void givenLambdaShortForm_whenSortingEntitiesByName_thenCorrectlySorted() {

List<Human> humans = Lists.newArrayList( new Human( "Sarah" , 10 ), new Human( "Jack" , 12 ));

humans.sort((h1, h2) -> h1.getName().compareTo(h2.getName()));

Assert.assertThat(humans.get( 0 ), equalTo( new Human( "Jack" , 12 )));

}

5、使用静态方法的引用来排序

public static int compareByNameThenAge(Human lhs, Human rhs) {

if (lhs.name.equals(rhs.name)) {

return lhs.age - rhs.age;

} else {

return lhs.name.compareTo(rhs.name);

}

}

humans.sort(Human::compareByNameThenAge);

@Test

public void givenMethodDefinition_whenSortingEntitiesByNameThenAge_thenCorrectlySorted() {

List<Human> humans = Lists.newArrayList( new Human( "Sarah" , 10 ), new Human( "Jack" , 12 ));

humans.sort(Human::compareByNameThenAge);

Assert.assertThat(humans.get( 0 ), equalTo( new Human( "Jack" , 12 )));

}

6、提取Comparator进行排序

@Test

public void givenInstanceMethod_whenSortingEntitiesByNameThenAge_thenCorrectlySorted() {

List<Human> humans = Lists.newArrayList( new Human( "Sarah" , 10 ), new Human( "Jack" , 12 ));

Collections.sort(humans, Comparator.comparing(Human::getName));

Assert.assertThat(humans.get( 0 ), equalTo( new Human( "Jack" , 12 )));

}

7、反转排序
JDK 8同样提供了一个有用的方法用来反转Comparator（reverse Comparator）——我们可以快速地利用它来反转我们的排序：

@Test

public void whenSortingEntitiesByNameReversed_thenCorrectlySorted() {

List<Human> humans = Lists.newArrayList(

new Human( "Sarah" , 10 ), new Human( "Jack" , 12 ));

Comparator<Human> comparator = (h1, h2) -> h1.getName().compareTo(h2.getName());

humans.sort(comparator.reversed());

Assert.assertThat(humans.get( 0 ), equalTo( new Human( "Sarah" , 10 )));

}

8、多条件排序

@Test

public void whenSortingEntitiesByNameThenAge_thenCorrectlySorted() {

List<Human> humans = Lists.newArrayList(

new Human( "Sarah" , 12 ), new Human( "Sarah" , 10 ), new Human( "Zack" , 12 ));

humans.sort((lhs, rhs) -> {

if (lhs.getName().equals(rhs.getName())) {

return lhs.getAge() - rhs.getAge();

} else {

return lhs.getName().compareTo(rhs.getName());

}

});

Assert.assertThat(humans.get( 0 ), equalTo( new Human( "Sarah" , 10 )));

}

9、多条件组合排序

@Test

public void givenComposition_whenSortingEntitiesByNameThenAge_thenCorrectlySorted() {

List<Human> humans = Lists.newArrayList(

new Human( "Sarah" , 12 ), new Human( "Sarah" , 10 ), new Human( "Zack" , 12 ));

humans.sort(Comparator.comparing(Human::getName).thenComparing(Human::getAge));

Assert.assertThat(humans.get( 0 ), equalTo( new Human( "Sarah" , 10 )));

}

10、总结