这里将演示 Java 8 中,几种使用 Ladmbda 结合 Comparator 进行 List 排序(升序或降序)的方式。
Comparator 排序
Comparator 是 Java 8 之前常用的排序方式,下面是排序 Person 类中的 age 字段的示例。
@Data
public class Person {
private String name;
private Integer age;
public Person(String name, Integer age) {
this.name = name;
this.age = age;
}
}
public class PersonTest {
@Test
public void testComparator (){
List<Person> list = new ArrayList<>();
list.add(new Person("老王", 20));
list.add(new Person("老李", 10));
list.add(new Person("老徐", 28));
list.add(new Person("老陈", 18));
list.add(new Person("老艾", 31));
Collections.sort(list, new Comparator<Person>() {
@Override
public int compare(Person o1, Person o2) {
return o1.getAge() - o2.getAge();
}
});
for (Person person : list) {
System.out.println(person);
}
}
}
输出结果:
Person(name=老李, age=10)
Person(name=老陈, age=18)
Person(name=老王, age=20)
Person(name=老徐, age=28)
Person(name=老艾, age=31)
这里是一个匿名内部类方式的实现,为了一行排序代码写的代码是不是有点多了?
2. Lambda 和 Comparator 排序
public class PersonTest {
@Test
public void testComparator () {
List<Person> list = new ArrayList<>();
list.add(new Person("老王", 20));
list.add(new Person("老李", 10));
list.add(new Person("老徐", 28));
list.add(new Person("老陈", 18));
list.add(new Person("老艾", 31));
sort(list);
list.forEach(System.out::println);
}
public List<Person> sort(List<Person> list) {
Comparator<Person> byAge = (Person o1, Person o2) -> o1.getAge().compareTo(o2.getAge());
list.sort(byAge);
return list;
}
}
输出结果:
Person(name=老李, age=10)
Person(name=老陈, age=18)
Person(name=老王, age=20)
Person(name=老徐, age=28)
Person(name=老艾, age=31)
也可以使用 Lambda 结合函数接口来完成 Comparator 的定义操作。
public List<Person> sort(List<Person> list) {
Comparator<Person> byAge = Comparator.comparing(Person::getAge);
list.sort(byAge);
return list;
}
当然也可以进一步简化代码,像下面这样。
list.sort(Comparator.comparing(Person::getAge));
当需要排其他字段排序,如 name 字段,可以直接改为。
list.sort(Comparator.comparing(Person::getName));
3. 排序反转
下面的示例演示按 age 字段降序和升序的排序方式。
public class PersonTest {
@Test
public void testComparator () {
List<Person> list = new ArrayList<>();
list.add(new Person("老王", 20));
list.add(new Person("老李", 10));
list.add(new Person("老徐", 28));
list.add(new Person("老陈", 18));
list.add(new Person("老艾", 31));
list.sort((p1, p2) -> p1.getAge() - p2.getAge());
list.forEach(System.out::println);
System.out.println("--------");
list.sort((p1, p2) -> p2.getAge() - p1.getAge());
list.forEach(System.out::println);
}
}
输出结果
Person(name=老李, age=10)
Person(name=老陈, age=18)
Person(name=老王, age=20)
Person(name=老徐, age=28)
Person(name=老艾, age=31)
----------
Person(name=老艾, age=31)
Person(name=老徐, age=28)
Person(name=老王, age=20)
Person(name=老陈, age=18)
Person(name=老李, age=10)
也可以用另外的一种方式:
Comparator<Person> comparing =Comparator.comparing(Person::getAge);
list.sort(comparing);
list.forEach(System.out::println);
System.out.println("--------");
list.sort(comparing.reversed());
list.forEach(System.out::println);
4. Lambda 和 Comparator 和 Stream 排序
有时需要使用 stream 的 API,顺便排序可以使用 stream 的 sorted 方法。
@Test
public void testComparator () {
List<Person> list = new ArrayList<>();
list.add(new Person("老王", 20));
list.add(new Person("老李", 10));
list.add(new Person("老徐", 28));
list.add(new Person("老陈", 18));
list.add(new Person("老艾", 31));
list.stream().sorted(Comparator.comparing(Person::getAge))
.forEach(System.out::println);
System.out.println("----------");
list.stream().sorted(Comparator.comparing(Person::getAge).reversed())
.forEach(System.out::println);
}
}
输出结果:
Person(name=老李, age=10)
Person(name=老陈, age=18)
Person(name=老王, age=20)
Person(name=老徐, age=28)
Person(name=老艾, age=31)
----------
Person(name=老艾, age=31)
Person(name=老徐, age=28)
Person(name=老王, age=20)
Person(name=老陈, age=18)
Person(name=老李, age=10)