Arrays.sort()适用于原生数组,Collections.sort()仅适用于List;Comparator有匿名类、方法引用、lambda三种写法,lambda最常用;sort时Comparator优先级高于Comparable;自定义Comparator需保证一致性、无副作用、线程安全。

Arrays.sort() 和 Collections.sort() 的适用场景区别
数组和集合的排序不能混用:对 int[] 用 Collections.sort() 会编译失败,因为后者只接受 List;而 Arrays.sort() 对 ArrayList 直接传参会报错,必须先转成数组或用其重载版本。
-
Arrays.sort()适用于原生数组(int[]、String[]、MyObj[]),也支持传入Comparator -
Collections.sort()只接受List实现(如ArrayList、LinkedList),底层调用的是Arrays.sort()的Object[]版本 - 对基本类型数组(如
int[])排序,只能用Arrays.sort();它不接受Comparator,因为基本类型无法参与泛型比较逻辑
Comparator 接口的三种写法及何时必须用 lambda
从 Java 8 起,Comparator 是函数式接口,但不是所有写法都等价。匿名内部类、静态方法引用、lambda 表达式在可读性和性能上差异明显。
- 匿名类适合复杂多字段逻辑,但冗长:
new Comparator
() { public int compare(Person a, Person b) { return Integer.compare(a.getAge(), b.getAge()); } } - 方法引用仅限单方法调用,比如
String::compareTo,不能组合条件 - lambda 最常用:
(a, b) -> Integer.compare(a.getAge(), b.getAge());注意返回值必须是int,不能写成return a.getAge() > b.getAge()这种布尔表达式 - 如果字段可能为
null,别直接链式调用a.getName().compareTo(b.getName()),应改用Comparator.nullsLast(Comparator.comparing(Person::getName))
Comparable 和 Comparator 混用时的优先级陷阱
当一个类同时实现了 Comparable(定义自然顺序)又传入了 Comparator(定制顺序),sort() 方法永远以 Comparator 为准,Comparable 完全被忽略。
-
TreeSet默认用Comparable,但如果构造时传入Comparator,则全部按该规则去重和排序 -
Arrays.sort(personArray)(无 comparator)会尝试调用person.compareTo(),若未实现Comparable则抛ClassCastException - 不要在
compareTo()里调用Comparator,这会造成循环依赖或逻辑混乱 - 若业务中存在多种排序需求(按年龄、按姓名、按创建时间),应统一提供多个静态
Comparator实例,而非让类实现Comparable
自定义 Comparator 中的稳定性与副作用风险
Java 的排序算法(如 Timsort)是稳定的,但前提是 compare() 方法满足“一致性”:对同一对对象多次调用必须返回相同结果;否则可能触发 IllegalArgumentException: Comparison method violates its general contract!
立即学习“Java免费学习笔记(深入)”;
- 避免在
compare()中修改对象状态(如调用setSortIndex()) - 禁止使用非确定性值,例如
new Date().getTime()或Math.random() - 字段类型不一致容易翻车:比如用
Double.compare(a.getScore(), b.getScore())处理null,但double基本类型无法为null,应确保字段是Double包装类 - 复合排序记得用
thenComparing()链式调用,而不是手动写嵌套if-else,否则易漏return 0导致逻辑错误
Map weightMap ),而该 map 在排序过程中被其他线程修改,结果就不可预测。










