Java中Collections.sort配合自定义Comparator实现灵活排序,核心是传入描述比较逻辑的对象而非依赖元素自身Comparable;需确保List可修改、类型匹配,并注意null安全与Lambda简洁写法。

Java 中用 Collections.sort 配合自定义 Comparator,核心是传入一个能描述“怎么比”的逻辑对象,而不是依赖元素自身实现 Comparable。这种方式更灵活,尤其适合对同一类对象按不同字段、多条件或运行时规则排序。
定义符合需求的 Comparator
Comparator 是函数式接口,只需实现 compare(T o1, T o2) 方法,返回负数(o1 在前)、0(相等)、正数(o2 在前)。推荐用 Lambda 表达式,简洁直观:
- 按字符串长度升序:
(s1, s2) -> Integer.compare(s1.length(), s2.length()) - 按 Person 的 age 升序,age 相同时按 name 字典序:
(p1, p2) -> { int c = Integer.compare(p1.getAge(), p2.getAge()); return c != 0 ? c : p1.getName().compareTo(p2.getName()); } - 降序可直接用
Comparator.reverseOrder()或在 Lambda 中翻转比较参数顺序
调用 Collections.sort 并传入 List 和 Comparator
确保传入的 List 是可修改的(如 new ArrayList()),且元素类型与 Comparator 声明的泛型一致。排序是原地修改,不返回新列表:
List<String> list = Arrays.asList("apple", "banana", "cat"); Collections.sort(list, (s1, s2) -> s1.length() - s2.length()); // 排序后 list 变为 ["cat", "apple", "banana"]- 若 List 是不可修改的(如
Arrays.asList()返回的),会抛UnsupportedOperationException;应先复制:new ArrayList(originalList)
利用 Comparator 静态方法链式构建复杂逻辑
Java 8+ 提供了丰富的静态工厂方法,让多级排序、空值处理更清晰安全:
立即学习“Java免费学习笔记(深入)”;
- 按 name 升序,null 排最后:
Comparator.comparing(Person::getName, Comparator.nullsLast(String::compareTo)) - 先按 age 升序,再按 salary 降序:
Comparator.comparing(Person::getAge).thenComparing(Person::getSalary, Comparator.reverseOrder()) - 忽略大小写排序:
Comparator.comparing(String::toLowerCase)
注意 null 安全和类型一致性
如果 List 中可能含 null,而 Comparator 没处理,运行时会抛 NullPointerException。务必显式用 nullsFirst() 或 nullsLast() 包装比较器。另外,Comparator 的泛型类型必须与 List 元素类型匹配,否则编译报错 —— 这是编译期保障,不是靠运行时猜测。


















