2011-02-03 37 views
0

我有一個自定義類型的數組,我想通過它的一個String屬性進行排序。出於某種原因,下面的代碼產生錯誤的結果。你能指出我可能犯了什麼錯誤嗎?通過字符串屬性對自定義類型數組排序?

class PatientLNComparator implements Comparator<Patient>{ 
     @Override 
     public int compare(Patient p1, Patient p2) { 
      String p1_LN = (p1 == null) ? null : p1.last_name; 
      String p2_LN = (p2 == null) ? null : p2.last_name; 

      if(p2_LN == null) 
        return -1; 
      else if(p1_LN == null) 
        return +1; 
      else if(p1_LN.equals(p2_LN)) 
        return 0; 
      else if(p1_LN.compareTo(p2_LN) > 0) 
        return -1; 
      else 
        return +1; 
     } 
} 
+1

你能給出一個錯誤結果的例子嗎?初步看來我認爲你在compareTo行中翻轉了標誌 – 2011-02-03 00:11:21

+0

由於所有的空檢查都是先完成的,你可以刪除`p2_LN`和`p1_LN`。 – Brian 2011-02-03 19:11:25

回答

2

開始時的一個問題 - 如果您爲兩位患者輸入空名稱或兩位患者爲空,則比較器不一致。特別是:

Patient p1 = null; 
Patient p2 = null; 

int x = comparator.compare(p1, p2); 
int y = comparator.compare(p2, p1); 

x的跡象,y應該有所不同 - 但他們都會爲-1。

之後,它取決於你想如何比較名稱。我通常會使用

return p1_LN.compareTo(p2_LN); 

如果要按升序排序。請注意,要排序降序順序,您不應該僅返回-p1_LN.compareTo(p2_LN),就好像比較返回Integer.MIN_VALUE一樣,否定將不起作用。相反,你想要返回p2_LN.compareTo(p1_LN);

請注意,如果您使用此方案,則不需要撥打p1_LN.equals(p2_LN) - 這將由compareTo呼叫處理。

1

我假設你想爲此自然字符串排序。

首先,您的compareTo分支會給出相反的結果。不知道這是否是你想要的或者不是你想要的(就像你在說p1的字符串低於p2時p1大於p2一樣)。

此外,您可以溝通if的.equals分支。 compareTo已經處理這種情況。

因此一個簡單的

if(p2_LN == null && p1_LN == null) 
    return 0; 
else if(p1_LN == null) 
    return +1; 
else if(p2_LN == null) 
    return -1; 
else return p1_LN.compareTo(p2_LN) 

就足夠了。

1

你想讓病人按姓氏字母順序排列,空病人和空姓前排名?

class PatientLNComparator implements Comparator<Patient>{ 
     @Override 
     public int compare(Patient p1, Patient p2) { 
      String p1_LN = (p1 == null) ? null : p1.last_name; 
      String p2_LN = (p2 == null) ? null : p2.last_name; 

      if (p1_LN == null && p2_LN == null) 
        return 0; 
      else if (p2_LN == null) 
        return -1; 
      else if(p1_LN == null) 
        return +1; 
      else 
        return p1_LN.compareTo(p2_LN); 
     } 
} 

是穩定的,它真的應該通過一些其他領域的訂單,如名字,當姓氏是相等的。

0

我會用GuavaOrdering類這樣的:

class Patient { 
    // ... 
    public static final Function<Patient, String> GET_LAST_NAME = 
     new Function<Patient, String>() { 
      public String apply(Patient from) { 
       if (from == null) return null; 
       return from.last_name; 
      } 
     }; 

    public static final Comparator<Patient> BY_LAST_NAME = 
     Ordering.natural() 
       .onResultOf(GET_LAST_NAME) 
       .nullsFirst(); 
} 

這將解決該問題與空值的不一致比較。它還可以很容易地添加二級訂單(例如名字):

public static final Comparator<Patient> BY_LAST_NAME = 
     Ordering.natural() 
       .onResultOf(GET_LAST_NAME) 
       .compound(Ordering.natural().onResultOf(GET_FIRST_NAME)) 
       .nullsFirst(); 
相關問題