Collections.sort()要求元素实现Comparable或传入Comparator,否则抛ClassCastException;自定义类需实现Comparable并正确重写compareTo;临时排序应使用Comparator.comparing链式调用;Collections.sort()与List.sort()均基于Timsort且原地修改列表。

Collections.sort() 只能对 ArrayList、LinkedList 等实现了 List 接口且元素实现了 Comparable 的集合排序;如果元素类型没实现 Comparable,或你想按非自然顺序排,必须传入 Comparator,否则运行时抛 ClassCastException。
为什么调用 Collections.sort() 会报 ClassCastException
常见于自定义类(如 User)未实现 Comparable,却直接调用 Collections.sort(users)。JVM 尝试把每个元素强转成 Comparable 来比较,失败就炸。
- 检查类是否实现了
Comparable:比如public class User implements Comparable - 确认
compareTo()方法返回int,且逻辑不返回null或未初始化字段 - 若只是临时按某字段排序(比如按年龄),别改类定义,直接传
Comparator
用 Comparator 实现多字段/逆序/空值安全排序
Java 8+ 推荐用 Comparator.comparing() 链式调用,比匿名内部类更简洁、不易出错。
Lists.sort(users, Comparator.comparing(User::getAge)
.thenComparing(User::getName, String.CASE_INSENSITIVE_ORDER)
.reversed()
.nullsLast());
-
reversed()是整个链的逆序,不是单个字段;要单字段逆序,写comparing(User::getAge).reversed() -
nullsLast()必须放在最后,否则会被后续thenComparing覆盖 - 避免用
Comparator.nullsFirst()处理可能为null的字段,除非你真希望null排最前
Collections.sort() 和 List.sort() 有什么区别?
两者底层都调用 Timsort,时间复杂度都是 O(n log n),但行为有关键差异:
-
Collections.sort(list)要求list是可修改的(比如非Collections.unmodifiableList()),否则抛UnsupportedOperationException -
list.sort(comparator)是List接口默认方法,语义更清晰,且部分 IDE 能更好推导泛型 - 对
Arrays.asList()返回的列表,两者等价;但对Stream.collect(Collectors.toList())结果,优先用.sort(),避免多一层静态方法调用
最容易被忽略的是:排序操作会**原地修改原列表**,没有副本。如果上游数据不能动,务必先 new ArrayList(originalList) 再排。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











