Collection sort()和stream.sorted()
Collection.sort()
1、基本用法
//方法内指定list对象
Collections.sort(list, (o1, o2) -> o1.getName().compareTo(o2.getName()));
//方法外指定list对象
list.sort((o1, o2) -> o1.getName().compareTo(o2.getName()));
//使用Comparator.comparing()
Collections.sort(list, Comparator.comparing(Object::getName));
//倒序
Collections.sort(list, Comparator.comparing(Object::getName).reversed());
//多条件排序
Collections.sort(list, Comparator.comparing(Object::getName).thenComparing(Object::getAge));
2、自定义排序规则
Collections.sort(list, Comparator.comparing(Object::getName, (s1, s2) -> {
return s2.compareTo(s1);
}));
3、兼容null元素排序;注:Comparator.naturalOrder()表示按照自然顺序排序,可换为其他排序规则。
//null元素排到前面
//Collections.sort(list, Comparator.nullsFirst(Comparator.comparing(Object::getName)));
//null元素排到后面
//Collections.sort(list, Comparator.nullsLast(Comparator.comparing(Object::getName)));
// 上述是错误写法,如果Object::getName为空,依然会抛出空指针异常,正确写法如下
//null元素排到前面
list.sort(Comparator.comparing(Object::getName, Comparator.nullsFirst(Comparator.naturalOrder())));
//null元素排到后面
list.sort(Comparator.comparing(Object::getName, Comparator.nullsLast(Comparator.naturalOrder())));
Collection.stream().sorted()
//对象集合以类属性一升序排序
list.stream().sorted(Comparator.comparing(类::属性一));
//对象集合以类属性一降序排序 注意两种写法
list.stream().sorted(Comparator.comparing(类::属性一).reversed());//先以属性一升序,结果进行属性一降序
list.stream().sorted(Comparator.comparing(类::属性一,Comparator.reverseOrder()));//以属性一降序
//对象集合以类属性一升序 属性二升序
list.stream().sorted(Comparator.comparing(类::属性一).thenComparing(类::属性二));
//对象集合以类属性一降序 属性二升序 注意两种写法
list.stream().sorted(Comparator.comparing(类::属性一).reversed().thenComparing(类::属性二));//先以属性一升序,反转即降序,再进行属性二升序
list.stream().sorted(Comparator.comparing(类::属性一,Comparator.reverseOrder()).thenComparing(类::属性二));//先以属性一降序,再进行属性二升序
//对象集合以类属性一降序 属性二降序 注意两种写法
list.stream().sorted(Comparator.comparing(类::属性一).reversed().thenComparing(类::属性二,Comparator.reverseOrder()));//先以属性一升序,反转即降序,再进行属性二降序
list.stream().sorted(Comparator.comparing(类::属性一,Comparator.reverseOrder()).thenComparing(类::属性二,Comparator.reverseOrder()));//先以属性一降序,再进行属性二降序
//对象集合以类属性一升序 属性二降序 注意两种写法
list.stream().sorted(Comparator.comparing(类::属性一).reversed().thenComparing(类::属性二).reversed());//先以属性一升序,反转即降序,再进行属性二升序,最后全部反转,于是属性一重新变为升序,属性二变为降序
list.stream().sorted(Comparator.comparing(类::属性一).thenComparing(类::属性二,Comparator.reverseOrder()));//先以属性一升序,再进行属性二降序
从最后一个例子可以看出reversed()和Comparator.reverseOrder()不仅是用法不一样,而且功能也不一样,reversed()用在comparing()或thenComparing()之外,是把之前所有的结果全部反转,Comparator.reverseOrder()用在comparing()或thenComparing()之内,只作用于当前排序条件的结果。所以,在实际使用中,推荐使用Comparator.reverseOrder(),这样代码逻辑更清晰。
sort()和stream().sorted()的区别
两者最大的区别是sort()没有返回值,stream().sorted()有返回值,如下例子写法均可:
//sort()不用返回赋值给list
list.sort(Comparator.comparing(Object::getDate, (d1, d2) -> {
return Long.compare(d2.getTime(), d1.getTime());
}));//stream().sorted()需要返回赋值给list,并且需要指定返回类型collect(Collectors.toList())
list = list.stream().sorted(Comparator.comparing(Object::getDate, (d1, d2) -> {
return Long.compare(d2.getTime(), d1.getTime());
})).collect(Collectors.toList());//可省略返回关键字return
list = list.stream().sorted(Comparator.comparing(Object::getDate, (d1, d2) ->
Long.compare(d2.getTime(), d1.getTime())
)).collect(Collectors.toList());//可直接用Object对象自定义排序规则,省略Comparator.comparing()
list = list.stream().sorted((o1, o2) ->
Long.compare(o2.getDate().getTime(),o1.getDate().getTime())
).collect(Collectors.toList());
此外,stream().sorted()可以搭配stream().map()使用,达到排序后返回Object对象某个属性集合的目的。
// 搭配过滤条件,并指定返回Object对象的某个属性。注意,filter是筛选出符合条件的元素,而不是筛选掉的意思。
List<String> ids = list.stream().
filter(o -> o.getDate() != null && o.getId() != null).
sorted(Comparator.comparing(Object::getDate)).
map(Object::getId).
collect(Collectors.toList());