Java中对引用类型数组使用Arrays.sort必须提供Comparator,否则抛ClassCastException;可用Lambda(如(s1,s2)->s1.length()-s2.length())、Comparator静态方法链式调用(如comparing().thenComparing())或实现Comparator接口。

Java 中对引用类型数组使用 Arrays.sort 时,必须提供自定义比较器(Comparator),否则会抛出 ClassCastException(因为引用类型默认不实现 Comparable)。写法核心是传入一个实现了 Comparator<t></t> 的对象,其中 T 是数组元素类型。
使用 Lambda 表达式(推荐,简洁)
Java 8+ 支持用 Lambda 直接定义比较逻辑,可读性高、代码少。
- 语法:`(a, b) -> { return 整数; }`,返回负数表示 a 在前,正数表示 b 在前,0 表示相等
- 按字符串长度升序:
Arrays.sort(strings, (s1, s2) -> s1.length() - s2.length()); - 按 Person 对象的 age 升序,name 降序(二级排序):
Arrays.sort(people, (p1, p2) -> {<br> int cmp = Integer.compare(p1.age, p2.age);<br> if (cmp != 0) return cmp;<br> return p2.name.compareTo(p1.name); // name 降序<br>});
使用 Comparator 静态方法链式调用(清晰、可复用)
利用 Comparator.comparing 及其组合方法,语义明确,适合多级排序或复用场景。
- 按 age 升序:
Arrays.sort(people, Comparator.comparing(p -> p.age)); - 先按 age 升序,age 相同再按 name 降序:
Arrays.sort(people,<br> Comparator.comparing((Person p) -> p.age)<br> .thenComparing(Person::getName, Comparator.reverseOrder()));
- 注意:Lambda 参数类型有时需显式声明(如上例中
(Person p)),避免编译错误
实现 Comparator 接口(适合复杂逻辑或需复用类)
当比较逻辑较重、涉及状态或需跨多处使用时,可单独定义类实现 Comparator。
立即学习“Java免费学习笔记(深入)”;
- 示例:
class PersonAgeNameComparator implements Comparator<Person> {<br> public int compare(Person p1, Person p2) {<br> if (p1.age != p2.age) return Integer.compare(p1.age, p2.age);<br> return p2.name.compareTo(p1.name); // name 降序<br> }<br>}
调用:Arrays.sort(people, new PersonAgeNameComparator()); - 也可定义为静态内部类或私有嵌套类,便于封装
注意事项与常见坑
-
不能对 null 元素直接比较:若数组含
null,Lambda 或comparing可能抛NullPointerException。应使用Comparator.nullsFirst()或nullsLast()包装,例如:Comparator.comparing((Person p) -> p.name, Comparator.nullsLast(String::compareTo)) -
避免整数溢出:不要直接用
a.field - b.field(如int值极大时)。优先用Integer.compare(a, b)等工具方法 -
数组类型必须是引用类型:
int[]等基本类型数组不能用带Comparator的sort,需用对应原始类型重载方法(如Arrays.sort(int[]))










