Java 8 引入了強大的 Comparator 靜態工廠方法與 List.sort() 實例方法,極大簡化了集合排序的代碼。本文通過豐富的示例,系統講解從基礎排序到複雜比較器鏈的構建技巧。
List<String> cities = Arrays.asList("Milan", "london", "San Francisco", "Tokyo", "New Delhi");
// 不區分大小寫排序
cities.sort(String.CASE_INSENSITIVE_ORDER);
// 結果:[london, Milan, New Delhi, San Francisco, Tokyo]
// 自然順序(大寫優先)
cities.sort(Comparator.naturalOrder());
// 結果:[Milan, New Delhi, San Francisco, Tokyo, london]
關鍵差異:String.CASE_INSENSITIVE_ORDER 忽略大小寫;Comparator.naturalOrder() 按 Unicode 值排序,大寫字母(A-Z: 65-90)排在小寫(a-z: 97-122)之前。
List<Integer> numbers = Arrays.asList(6, 2, 1, 4, 9);
numbers.sort(Comparator.naturalOrder());
// 結果:[1, 2, 4, 6, 9]
Integer 實現了 Comparable,直接使用自然順序即可。
Comparator.comparing()record Movie(String title, double rating, boolean starred) {}
List<Movie> movies = Arrays.asList(
new Movie("Lord of the rings", 8.8, true),
new Movie("Back to the future", 8.5, false),
new Movie("Carlito's way", 7.9, true),
new Movie("Pulp fiction", 8.9, false)
);
// 按標題排序(String 實現 Comparable)
movies.sort(Comparator.comparing(Movie::title));
// 按評分降序排序
movies.sort(Comparator.comparingDouble(Movie::rating).reversed());
comparing() 接收鍵提取函數,自動推導比較邏輯;comparingDouble()、comparingInt()、comparingLong() 針對基本類型優化,避免裝箱開銷。
當需要非標準排序邏輯時(如:置頂 starred 影片優先),可使用 Lambda 或匿名類:
// Lambda 寫法
movies.sort((m1, m2) -> {
if (m1.starred() == m2.starred()) return 0;
return m1.starred() ? -1 : 1;
});
// 等價的 comparing 寫法
movies.sort(Comparator.comparing(Movie::starred, (s1, s2) ->
s1 == s2 ? 0 : (s1 ? -1 : 1)
));
thenComparing() 支持多級排序邏輯,優先級由調用順序決定:
movies.sort(Comparator.comparing(Movie::starred).reversed()
.thenComparing(Comparator.comparing(Movie::rating).reversed()));
上述代碼實現:優先按 starred 降序(true 在前),再按 rating 降序。輸出結果:
Movie[starred=true, title='Lord of the rings', rating=8.8] Movie[starred=true, title="Carlito's way", rating=7.9] Movie[starred=false, title='Pulp fiction', rating=8.9] Movie[starred=false, title='Back to the future', rating=8.5]
Java 7 使用 Collections.sort(list, comparator);Java 8 推薦使用 list.sort(comparator),更符合面向對象設計,且支持默認方法擴展。