本文总结下集合元素排序的常用 API:
基于可比较对象排序
如果集合元素已实现 Comparable
接口,可以直接使用 naturalOrder
、reverseOrder
方法进行排序:
1 2 3 4 5 6 7 8 9
| List<Integer> integers = Arrays.asList(3, 1, 2, 4);
integers.sort(Comparator.naturalOrder());
integers.sort(Comparator.reverseOrder());
|
上述排序不支持 null
值(会抛 NPE 异常),如果自定义实现的话,代码比较冗余,容易出错:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| List<Integer> integers = Arrays.asList(3, 1, null, 2, 4);
integers.sort((o1, o2) -> { if (o1 != null && o2 != null) { return o1.compareTo(o2); } else { return o1 == null ? -1 : 1; } });
integers.sort((o1, o2) -> { if (o1 != null && o2 != null) { return o2.compareTo(o1); } else { return o1 == null ? 1 : -1; } });
|
可采用 nullsFirst
、nullsLast
方法兼容 null
值情况:
1 2 3 4 5 6 7 8 9
| List<Integer> integers = Arrays.asList(3, 1, null, 2, 4);
integers.sort(Comparator.nullsFirst(Comparator.naturalOrder()));
integers.sort(Comparator.nullsLast(Comparator.reverseOrder()));
|
基于不可比较对象排序
例子:
1 2 3 4 5 6
| @Data @AllArgsConstructor public class IdName { private Integer id; private String name; }
|
如果集合元素未实现 Comparable
接口,需要抽取关键字(关键字需实现 Comparable
接口)排序:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| List<IdName> idNames = Arrays.asList( new IdName(3, "Pete"), new IdName(1, "Tom"), new IdName(2, "Ben"), new IdName(2, "Allen"));
idNames.sort(Comparator.comparing(IdName::getId));
idNames.sort(Comparator.comparing(IdName::getId, Comparator.nullsLast(Comparator.naturalOrder())));
idNames.sort(Comparator.comparing(IdName::getId) .thenComparing(IdName::getName));
idNames.sort(Comparator.comparing(IdName::getId) .thenComparing(IdName::getName) .reversed());
|
参考
《java comparator 升序、降序、倒序从源码角度理解》
https://blog.csdn.net/weixin_44270183/article/details/87026995