@FunctionalInterface
public interface Comparator {
int compare(T o1, T o2); // 負數:o1o2
}
Studentclass Student {
private String name; private int age;
// 建構子、getter/setter、toString 略
}
Collections.sort(list, new Comparator() {
@Override public int compare(Student s1, Student s2) {
int nameCmp = s1.getName().compareTo(s2.getName());
if (nameCmp != 0) return nameCmp; // 主鍵:姓名
return s1.getAge() - s2.getAge(); // 次鍵:年齡
}
});
// 靜態導入:import static java.util.Comparator.*;
list.sort(comparing(Student::getName)
.thenComparingInt(Student::getAge));
鏈式方法:
comparing(Function):主鍵thenComparing(Function):次鍵(支援 Comparator)thenComparingInt/Long/Double:基本型別避免裝箱reversed():倒序nullsFirst/Last():空值處理public class ComparatorDemo {
public static void main(String[] args) {
List list = Arrays.asList(
new Student("abc", 10), new Student("bdc", 10),
new Student("bdd", 5), new Student("aad", 30)
);
// 姓名升序,同年齡升序
list.sort(comparing(Student::getName).thenComparingInt(Student::getAge));
list.forEach(s -> System.out.println(s.getAge() + ":" + s.getName()));
}
}
輸出:
30:aad 10:abc 10:bdc 5:bdd
| 錯誤 | 後果 | 正確做法 |
|---|---|---|
減法溢位 a - b | 大數相減可能溢位導致排序錯誤 | 用 Integer.compare(a,b) 或 thenComparingInt |
| 違反傳遞性 | sort 拋 IllegalArgumentException | 確保 compare(a,b) 與 equals 一致 |
| 修改排序中元素 | 行為未定義 | 排序前完成所有修改 |
| 忽略 null | NPE | nullsFirst() 或預設值 |
public class StudentComparator implements Comparator {
@Override public int compare(Student s1, Student s2) {
int c = s1.getName().compareTo(s2.getName());
return c != 0 ? c : Integer.compare(s1.getAge(), s2.getAge());
}
}
// 使用
list.sort(new StudentComparator());
comparing/thenComparingComparator 實作類thenComparingInt/Long/DoubleSerializable 的具名類