Skip to content

集合排序: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.sortArrays.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 排序数组,两者都是稳定排序。


相关链接

基于 VitePress 构建