2011-02-03 65 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(); 
相关问题