簡體   English   中英

Java比較器:兩個排序條件

[英]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實現是HashSetTreeSet

  • 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM