在Java中,Comparator接口主要用于實現自定義排序邏輯,適用于未實現Comparable接口或需要覆蓋默認比較規則的場景。以下是核心使用方法和注意事項:
一、基礎用法
?匿名內部類實現?
傳統方式通過匿名內部類重寫compare()
方法,例如對整數降序排序:List<Integer> list = Arrays.asList(3, 1, 2); list.sort(new Comparator<Integer>() { @Override public int compare(Integer o1, Integer o2) {// 降序 return o2 - o1; } } );
此方式在Java 8之前常見。
?Lambda表達式簡化?
Java 8后可用Lambda替代匿名類,代碼更簡潔:list.sort((o1, o2) -> o2 - o1);
或使用方法引用:
list.sort(Comparator.reverseOrder());
適用于簡單排序場景。
二、高級特性
?多條件排序?
使用thenComparing()
實現多級排序,例如先按年齡升序,再按姓名降序:List<Person> people = ...; people.sort( Comparator.comparing(Person::getAge) .thenComparing(Comparator.comparing(Person::getName).reversed() ) );
支持鏈式調用,靈活組合排序規則。
?處理null值?
需顯式處理null避免NullPointerException
,例如將null排在末尾:list.sort((a, b) -> {if (a == null) return 1;if (b == null) return -1; return a.compareTo(b);});
注意違反自反性會導致
Comparison method violates its general contract
錯誤。
三、Comparator與Comparable對比
?維度? | ?Comparator? | ?Comparable? |
---|---|---|
實現位置 | 獨立類或匿名類 | 目標類內部實現 |
排序規則 | 支持多種自定義規則 | 僅提供單一自然排序 |
侵入性 | 無侵入,不影響原有類 | 需修改類結構 |
典型應用場景 | 第三方類排序、多規則排序 | 類自身有明確排序邏輯(如String) |
優先使用Comparator實現靈活排序,尤其是需要動態調整規則時。
四、常見問題
- ?整數溢出風險?
避免直接返回o1 - o2
,應使用Integer.compare(o1, o2)。
- ?JDK8增強方法?
Comparator.naturalOrder()
:自然排序Comparator.nullsFirst()
:將null置于開頭Comparator.comparingInt()
:避免裝箱開銷68。
通過合理應用Comparator,可高效實現復雜排序需求,同時保持代碼可維護性。
Java 8的?Stream API?提供了強大的List排序功能,主要通過sorted()
方法實現,支持自然排序、自定義排序以及多條件組合排序。以下是核心用法總結:
1. 基礎排序
- ?自然排序(升序)?:直接調用
sorted()
方法,元素需實現Comparable
接口list.stream().sorted().collect(Collectors.toList());
- ?降序排序?:通過
Comparator.reverseOrder()
或reversed()
方法list.stream().sorted(Comparator.reverseOrder()).collect(Collectors.toList());// 或 list.stream().sorted(Comparator.comparing(Person::getAge).reversed()).collect(Collectors.toList());
2. 自定義排序
- ?單字段排序?:使用
Comparator.comparing()
指定字段list.stream().sorted(Comparator.comparing(Student::getScore)).collect(Collectors.toList());
- ?多字段排序?:通過
thenComparing()
鏈式調用list.stream() .sorted(Comparator.comparing(Student::getAge) .thenComparing(Student::getName)) .collect(Collectors.toList());
3. 空值處理
- ?空值優先/后置?:使用
Comparator.nullsFirst()
或Comparator.nullsLast()
list.stream() .sorted(Comparator.comparing(Student::getAge, Comparator.nullsFirst(Integer::compareTo))) .collect(Collectors.toList());
4. 性能提示
sorted()
操作對大型流可能較昂貴,若數據已排序可跳過此操作2- 復雜排序建議預編譯
Comparator
以減少重復計算9
完整示例:
List<Student> students = Arrays.asList( new Student("Alice", 25), new Student("Bob", 20) );List<Student> sorted = students.stream() .sorted(Comparator.comparing(Student::getAge).reversed()) .collect(Collectors.toList());