compareTo 是 java.lang.Comparable 介面中的唯一方法,若陣列內的元素皆有實現 Comparable,那麼就能用 Arrays.sort 來排序,同時亦可以與 collection 下的資料結構來進行協作。
實作 compareTo 時需要注意幾點:(經 sgn 方法處理後結果為 1、0 或 -1)
- sgn(x.compareTo(y)) == -sgn(y.compareTo(x)),如果 x.compareTo(y) 丟出 exception,那 y.compareTo(x) 亦會丟出 exception。
- 保證遞移性,當 x.compareTo(y) > 0 && y.compareTo(z) > 0 時,表示 x.compareTo(z) > 0。
- x.compareTo(y) == 0 時,sgn(x.compareTo(z)) 須與 sgn(y.compareTo(z)) 相同。
- 強烈建議 x.compareTo(y) == 0 時, x.equals(y) 為 true。
BigDecimal a = new BigDecimal("1.0");
BigDecimal b = new BigDecimal("1.00");
System.out.println("a.equals(b) is " + a.equals(b)); // false
System.out.println("a.compareTo(b) is " + (a.compareTo(b) == 0)); // true
Set<BigDecimal> hashSet = new HashSet<>();
hashSet.add(a);
hashSet.add(b);
System.out.println(hashSet.size()); // 2
Set<BigDecimal> treeSet = new TreeSet<>();
treeSet.add(a);
treeSet.add(b);
System.out.println(treeSet.size()); // 1
在 compareTo 裡使用 < 及 > 是容易混淆的,建議使用 Short.compare 或 Double.compare 等方法。Java 8 提出 Comparator 介面,它包含相當多比較方法,像是 thenComparing 及 thenComparingInt,十分方便。有關 Comparator 及 Lambda 等用法,後續有機會再介紹。// java.util.Comparator source code
default Comparator<T> thenComparing(Comparator<? super T> other) {
Objects.requireNonNull(other);
return (Comparator<T> & Serializable) (c1, c2) -> {
int res = compare(c1, c2);
return (res != 0) ? res : other.compare(c1, c2);
};
}
// comparator
private static final Comparator COMPARATOR =
Comparator.comparing(Seat::getRoom).thenComparing(Seat::getDesk);
轉載請註明原文網址 https://cookieandcoketw.blogspot.com/2020/07/effective-java-14-comparable.html
沒有留言:
張貼留言