Java中用Collections.sort()配合Lambda排序List最常用,需确保List非null且元素类型一致;自定义类须传Comparator,基础类型可直接排序;Lambda写法简洁但要注意整数溢出、字符串大小写等细节;多字段排序推荐用Comparator链式方法,语义清晰且null安全;ArrayList性能好,LinkedList应转ArrayList再排序,不可修改原列表时用Stream.sorted。

直接用 Collections.sort() 配合 Lambda 表达式,是 Java 中对 List 排序最常用、最轻量的实战方案。它原地修改列表,不创建新集合,适合大多数业务场景,关键在于写法安全、逻辑清晰、避免踩坑。
确保排序前提成立
调用前必须确认两点:
- 目标 List 不为 null,且元素类型一致;
- 若元素是自定义类(如 User、Order),不能直接调用无参 sort,否则抛 ClassCastException —— 必须显式传入 Comparator。
基础类型(String、Integer)或已实现 Comparable 的类可直接用 Collections.sort(list);但多数业务实体需靠 Lambda 或 Comparator 构建规则。
Lambda 写比较器:简洁又可控
一行 Lambda 就是一个 Comparator 实例,比匿名内部类更直观。注意三点:
立即学习“Java免费学习笔记(深入)”;
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
- 用
Integer.compare(a, b)替代a - b,防止整数溢出; - 字符串升序用
s1.compareTo(s2),降序就写成s2.compareTo(s1); - 忽略大小写排序:用
String.CASE_INSENSITIVE_ORDER.compare(s1, s2)。
示例:按年龄升序,年龄相同时按姓名降序
Collections.sort(users, (u1, u2) -> {
int ageCmp = Integer.compare(u1.getAge(), u2.getAge());
if (ageCmp != 0) return ageCmp;
return u2.getName().compareTo(u1.getName()); // 姓名降序
});多字段排序推荐链式构建
当排序逻辑稳定、需复用或测试时,优先用 Comparator 静态链式方法,语义明确、null 安全、易组合:
-
Comparator.comparing(User::getAge):主键升序; -
.thenComparing(User::getScore, Comparator.nullsLast(Comparator.reverseOrder())):次键降序,null 排最后; -
.thenComparing(User::getName, String::compareTo):末级字典序升序。
最终可封装为常量:
public static final Comparator<User> BY_AGE_SCORE_NAME =
Comparator.comparing(User::getAge)
.thenComparing(User::getScore, Comparator.nullsLast(Comparator.reverseOrder()))
.thenComparing(User::getName);后续直接 Collections.sort(users, BY_AGE_SCORE_NAME) 即可。
注意性能与适用边界
Collections.sort() 底层调用 Arrays.sort(),依赖随机访问,因此:
- 对
ArrayList效率高(O(n log n)); - 对
LinkedList性能差(每次 get(i) 是 O(n),整体退化为 O(n² log n)),应先转成 ArrayList 再排序; - 若不允许修改原列表,改用
list.stream().sorted(...).collect(Collectors.toList()),但会额外占用内存。

















