排序方法sort
List和Stream中都有sort方法, 可以借助Comparator比较器快速实现列表排序
1.按年龄正序排(从小到大)
public class Test {
String name;
Integer age;
Double height;
public static void main(String[] args) {
List<Test> l = new ArrayList<>();
//直接对列表排序
l.sort(Comparator.comparing(Test::getAge));
//在stream中对列表排序
l.stream().sorted(Comparator.comparing(Test::getAge)).collect(Collectors.toList());
}
}
2.多字段排序: 先按年龄正序, 再按姓名正序, 最后按身高正序
l.sort(Comparator.comparing(Test::getAge)
.thenComparing(Test::getName)
.thenComparing(Test::getHeight));
3.复杂排序: 年龄18-65的在最前, 年龄0-17的在中间, 年龄65+的在最后, 同时三个年龄段都按年龄正序排列
l.sort(Comparator.comparing((Function<Test, Integer>) test -> {
if(18 <= test.getAge() && test.getAge() <= 65 ){
return -1;
} else if(0 <= test.getAge() && test.getAge() <= 17 ) {
return 0;
} else{
return 1;
}
}).thenComparing(Test::getAge));
倒序方法reversed
reversed是Comparator比较器中的方法, 用来实现倒序排序
1.按年龄倒序(从大到小)
l.sort(Comparator.comparing(Test::getAge).reversed());
2.多字段排序: 先按年龄倒序, 再按姓名倒序, 最后按身高倒序
l.sort(Comparator.comparing(Test::getAge)
.thenComparing(Test::getName)
.thenComparing(Test::getHeight).reversed());
reversed方法会把往前的排序字段都反转取倒序, 所以如果三个字段都是倒序, 则只需在最后加一个reversed即可
3.多字段排序: 先按年龄倒序, 再按姓名正序, 最后按身高倒序
多次使用reversed可以实现多字段不同顺序的排序
l.sort(Comparator.comparing(Test::getAge).reversed()
.thenComparing(Test::getName).reversed()
.thenComparing(Test::getHeight).reversed());
避免空指针异常
排序方法报出的空指针异常一般分为两种: 对象为空和对象的排序字段为空
比较器中有两个方法, Comparator.nullsFirst和Comparator.nullsLast, 顾名思义一个把null放在最前, 一个把null放在最后. 解决两种空指针异常都要用这两个方法, 但用法不同
1.解决对象为空的情况
l.add(null);
l.add(new Test("a", 20, 185d));
l.sort(Comparator.nullsFirst(Comparator.comparing(Test::getAge)));
2.解决对象排序字段为空的情况
l.add(new Test("a", null, 185d));
l.add(new Test("b", 21, 180d));
l.sort(Comparator.nullsFirst(Comparator.comparing(Test::getAge)));
l.sort(Comparator.comparing(Test::getAge, Comparator.nullsLast(Integer::compareTo)));
3.两种情况都可能发生的话就一起用
l.sort(Comparator.nullsFirst(Comparator.comparing(Test::getAge, Comparator.nullsLast(Integer::compareTo))));