集合排序:Collections 和 Arrays
排序方法一览
Java 提供两套排序 API:
Collections.sort(list) ← 排序 List
Arrays.sort(array) ← 排序数组Collections.sort:List 的排序
自然顺序排序
java
List<Integer> numbers = new ArrayList<>(Arrays.asList(5, 2, 8, 1, 9));
Collections.sort(numbers);
System.out.println(numbers); // [1, 2, 5, 8, 9]
List<String> words = new ArrayList<>(Arrays.asList("banana", "apple", "cherry"));
Collections.sort(words);
System.out.println(words); // [apple, banana, cherry]降序排列
java
List<Integer> numbers = new ArrayList<>(Arrays.asList(5, 2, 8, 1, 9));
// 方式 1:reverseOrder
Collections.sort(numbers, Collections.reverseOrder());
System.out.println(numbers); // [9, 8, 5, 2, 1]
// 方式 2:reversed()(JDK 11+)
numbers.sort(Comparator.reverseOrder());
// 方式 3:自定义降序
numbers.sort((a, b) -> b - a);Arrays.sort:数组的排序
基本类型 vs 对象数组
java
int[] ints = {5, 2, 8, 1, 9};
Arrays.sort(ints);
System.out.println(Arrays.toString(ints)); // [1, 2, 5, 8, 9]
String[] strings = {"banana", "apple", "cherry"};
Arrays.sort(strings);
System.out.println(Arrays.toString(strings)); // [apple, banana, cherry]部分排序
只排序数组的某个区间:
java
int[] arr = {9, 8, 7, 6, 5, 4, 3, 2, 1};
Arrays.sort(arr, 0, 5); // 只排序前 5 个:arr[0] ~ arr[4]
System.out.println(Arrays.toString(arr)); // [5, 6, 7, 8, 9, 4, 3, 2, 1]并行排序:parallelSort
大数据量时并行排序更快(JDK 8+):
java
int[] large = new int[10_000_000];
// ...
Arrays.parallelSort(large); // 自动利用多核并行排序自定义排序:Comparator
按字段排序
java
List<Student> students = Arrays.asList(
new Student("张三", 85),
new Student("李四", 92),
new Student("王五", 85)
);
// 按分数升序
students.sort(Comparator.comparingInt(Student::getScore));
// 按分数降序
students.sort(Comparator.comparingInt(Student::getScore).reversed());
// 先按分数降序,再按姓名升序
students.sort(
Comparator.comparingInt(Student::getScore).reversed()
.thenComparing(Student::getName)
);Lambda 表达式排序
java
List<String> words = new ArrayList<>(Arrays.asList("hi", "hello", "hey"));
// 按长度排序
words.sort(Comparator.comparingInt(String::length));
System.out.println(words); // [hi, hey, hello]
// 按长度降序
words.sort(Comparator.comparingInt(String::length).reversed());reverse / shuffle / swap
reverse:反转
java
List<Integer> list = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5));
Collections.reverse(list);
System.out.println(list); // [5, 4, 3, 2, 1]shuffle:随机打乱
java
List<String> cards = new ArrayList<>(Arrays.asList("A", "B", "C", "D", "E"));
// 随机打乱
Collections.shuffle(cards);
System.out.println(cards); // 随机顺序
// 指定随机数种子(可复现)
Collections.shuffle(cards, new Random(42));swap:交换元素
java
List<Integer> list = new ArrayList<>(Arrays.asList(1, 2, 3));
Collections.swap(list, 0, 2);
System.out.println(list); // [3, 2, 1]排序的稳定性
稳定性 = 相等的元素,排序后保持原有顺序。
java
List<Student> students = new ArrayList<>(Arrays.asList(
new Student("张三", 85),
new Student("李四", 92),
new Student("王五", 85),
new Student("赵六", 92)
));
// 第一次:按分数升序
students.sort(Comparator.comparingInt(Student::getScore));
// [张三(85), 王五(85), 李四(92), 赵六(92)]
// 注意:张三在王五前面(原始顺序保持)
// 第二次:按姓名升序
students.sort(Comparator.comparing(Student::getName));
// [李四(92), 王五(85), 张三(85), 赵六(92)]
// 注意:分数相等的,张三(85) 和王五(85) 仍然保持第一次排序的相对顺序Java 的 Collections.sort 和 Arrays.sort(对象数组) 都是稳定排序。
常见错误
错误 1:对无序 List 使用 binarySearch
java
List<Integer> list = new ArrayList<>(Arrays.asList(3, 1, 4, 1, 5));
// ❌ 无序列表,binarySearch 结果不确定
int index = Collections.binarySearch(list, 3);
System.out.println(index); // 可能不对!
// ✅ 先排序
Collections.sort(list);
int correct = Collections.binarySearch(list, 3); // 正确错误 2:排序和查找的比较器不一致
java
List<String> list = Arrays.asList("a", "B", "c");
// 排序用自然顺序(大小写敏感)
Collections.sort(list); // [B, a, c]
// ❌ 查找用不区分大小写
Collections.binarySearch(list, "A", String.CASE_INSENSITIVE_ORDER); // -1(找不到)
// ✅ 必须用相同的比较器
Collections.sort(list, String.CASE_INSENSITIVE_ORDER);
Collections.binarySearch(list, "A", String.CASE_INSENSITIVE_ORDER); // 找到错误 3:基本类型数组用并行排序反而更慢
java
int[] small = {5, 3, 8, 1};
// ❌ 小数组用并行排序,开销更大
Arrays.parallelSort(small); // 不值得
// ✅ 小数组用普通排序
Arrays.sort(small);
// parallelSort 适用于 >10000 元素总结
| 要点 | 说明 |
|---|---|
| Collections.sort | 排序 List(会修改原列表) |
| Arrays.sort | 排序数组(会修改原数组) |
| sort + Comparator | 自定义排序规则 |
| reverseOrder | 降序排列 |
| reverse/shuffle/swap | 集合操作工具 |
| 稳定性 | 相等元素保持原有顺序 |
| binarySearch | 必须先排序 |
一句话:
Collections.sort排序 List,Arrays.sort排序数组,两者都是稳定排序。
