[英]Java comparator: Two ordering criteria
我有一個簡單的類,其中包含一個字符串(名稱)和一個整數(年齡)。 應存儲在集合中的對象不得具有雙名值,並且應根據年齡的降序進行排序。 第一個代碼示例刪除所有雙精度名稱,但不包含第二個排序條件:
public int compare(Person p1, Person p2) {
int reVal = 1;
if(p1.getName().compareTo(p2.getName()) != 0){
reVal = 1;
}
else {
reVal = 0;
}
return reVal;
}
下一個示例比較器將對其余對象集進行排序,這些對象集不包含任何重復名稱:
public int compare(Person p1, Person p2) {
boolean ageGt = (p1.getAge() > p2.getAge());
int reVal = 1;
if(p1.getName().compareTo(p2.getName()) != 0){
if(scoreGt)
reVal = -1;
else
reVal = 1;
}
else {
reVal = 0;
}
return reVal;
}
第二個比較器根據對象的年齡值正確地對其排序,但是它允許使用雙名,這是我不明白的,因為外部if語句已經檢查了兩個對象的名稱是否相等。 為什么會這樣呢?
您這里有一個基本問題:您希望同時測試唯一性並訂購條目。 沒有內置集合可以同時檢查條目是否相等以及它們的比較是否為0。
例如,兩個Set
實現是HashSet
和TreeSet
:
HashSet
使用Object
的.equals()
/ .hashCode()
進行相等性測試; TreeSet
使用Comparator
(或對象的Comparable
功能,如果實現的話)來測試是否相等。 這不是完全一樣的事情。 實際上,對於一個特定的JDK類,即BigDecimal
,這可能會非常令人驚訝:
final BigDecimal one = new BigDecimal("1");
final BigDecimal oneDotZero = new BigDecimal("1.0");
final Set<BigDecimal> hashSet = new HashSet<>();
// BigDecimal implements Comparable of itself, so we can use that
final Set<BigDecimal> treeSet = new TreeSet<>();
hashSet.add(one);
hashSet.add(oneDotZero);
// hashSet's size is 2: one.equals(oneDotZero) == false
treeSet.add(one);
treeSet.add(oneDotZero);
// treeSet's size is... 1! one.compareTo(oneDotZero) == 0
你們不能都吃蛋糕。 在這里,要根據名稱測試唯一性,並根據年齡進行比較,則必須使用Map
。
為了獲得人員的排序列表,您將必須復制此地圖的.values()
作為列表,並使用Collections.sort()
。 如果使用番石榴,則后一部分就像Ordering.natural().sortedCopy(theMap.values())
一樣簡單,只要您的值實現Comparable
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.