排序是基礎演算法,Java 提供 `Arrays.sort`(陣列)、`Collections.sort`(List)、`Stream.sorted`(流式)三大入口,底層統一使用 **TimSort(合併排序 + 插入排序混合)**。本文系統闡述 API 用法、比較器策略、效能特徵與避坑指南。
int[] arr = {5, 2, 8, 1, 9, 3};
Arrays.sort(arr); // 升序:[1, 2, 3, 5, 8, 9]
// 基本型別無降序,需自行反轉或轉物件陣列
String[] strs = {"banana", "apple", "cherry"};
Arrays.sort(strs); // 自然序:按 Comparable 實現
// 自定義比較器
Arrays.sort(strs, (a, b) -> b.length() - a.length()); // 長度降序
Arrays.sort(strs, Comparator.comparing(String::length).reversed()); // 同前
Arrays.sort(arr, 1, 4); // 排索引 1 到 3(含頭不含尾)
Arrays.sort(strs, 0, 2, Comparator.reverseOrder());
Arrays.parallelSort(arr); // 多核並行,大陣列(>10000)顯著加速
Arrays.parallelSort(strs, Comparator.naturalOrder());
List list = new ArrayList<>(Arrays.asList("banana", "apple", "cherry"));
Collections.sort(list); // 自然序,修改原列表
Collections.sort(list, Comparator.reverseOrder()); // 降序
list.sort(Comparator.naturalOrder()); // 介面預設方法,更直觀
list.sort(Comparator.comparing(String::length).thenComparing(String::compareTo));
List sorted = list.stream().sorted().collect(Collectors.toList());
// 或
List sorted = new ArrayList<>(list);
sorted.sort(Comparator.naturalOrder());
Comparator natural = Comparator.naturalOrder();
Comparator reverse = Comparator.reverseOrder();
Comparator nullsFirst = Comparator.nullsFirst(natural);
Comparator nullsLast = Comparator.nullsLast(natural);
class User { String name; int age; int score; }
// 單鍵
Comparator byAge = Comparator.comparing(User::getAge);
Comparator byName = Comparator.comparing(User::getName, String.CASE_INSENSITIVE_ORDER);
// 多鍵:年齡升序 → 分數降序 → 姓名升序
Comparator multi = Comparator
.comparing(User::getAge)
.thenComparing(Comparator.comparing(User::getScore).reversed())
.thenComparing(User::getName);
// 處理 null
Comparator safe = Comparator
.comparing(User::getName, Comparator.nullsFirst(String::compareTo));
Comparator byAge = Comparator.comparingInt(User::getAge);
Comparator byScore = Comparator.comparingDouble(User::getScore);
Comparator byLong = Comparator.comparingLong(User::getId);
List users = ...;
// 自然序
List sorted = users.stream().sorted().collect(Collectors.toList());
// 比較器
List sorted = users.stream()
.sorted(Comparator.comparing(User::getAge).reversed())
.collect(Collectors.toList());
// 並行排序(大數據量)
List sorted = users.parallelStream()
.sorted(Comparator.comparing(User::getScore))
.collect(Collectors.toList());
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
@State(Scope.Thread)
public class SortBenchmark {
@Param({"1000", "10000", "100000", "1000000"})
int size;
int[] arr;
Integer[] objArr;
List list;
@Setup
public void setup() {
arr = new int[size];
objArr = new Integer[size];
list = new ArrayList<>(size);
Random r = new Random(42);
for (int i = 0; i < size; i++) {
int v = r.nextInt(size);
arr[i] = v;
objArr[i] = v;
list.add(v);
}
}
@Benchmark public void arraysPrimitive() { Arrays.sort(arr.clone()); }
@Benchmark public void arraysObject() { Arrays.sort(objArr.clone()); }
@Benchmark public void arraysParallel() { Arrays.parallelSort(arr.clone()); }
@Benchmark public void collectionsSort() { Collections.sort(new ArrayList<>(list)); }
@Benchmark public void listSort() { new ArrayList<>(list).sort(null); }
@Benchmark public void streamSort() { list.stream().sorted().collect(Collectors.toList()); }
@Benchmark public void parallelStreamSort() { list.parallelStream().sorted().collect(Collectors.toList()); }
/* 典型結果(毫秒):
size=1K arraysP: 0.2 arraysO: 0.5 parallel: 0.3 coll: 0.6 list: 0.6 stream: 1.2 pStream: 1.5
size=10K arraysP: 2.5 arraysO: 6 parallel: 1.8 coll: 7 list: 7 stream: 14 pStream: 8
size=100K arraysP: 30 arraysO: 70 parallel: 18 coll: 85 list: 85 stream: 170 pStream: 60
size=1M arraysP: 350 arraysO: 850 parallel: 180 coll: 1000 list: 1000 stream: 2000 pStream: 550
*/
}
**基本型別用 `Arrays.sort/parallelSort`,物件用 `List.sort(Comparator)`,多鍵用 `comparing().thenComparing()`,大數據並行,小數據串行**。掌握 TimSort 特性(部分有序極快、穩定排序)、比較器鏈式組合、基本型別專用比較器避免裝箱,才能寫出高效、正確、優雅的排序代碼。