2014-09-29 76 views
2

我有一個程序,其中有一個名稱列表,以及有多少人擁有該名稱。我想按字母順序排列名稱,同時也將計數從最大到最小。如果名稱具有相同的計數,則按名稱的字母順序排列。我想出瞭如何以abc的順序輸入名字,並想出如何將計數最大化到最小,但我無法弄清楚如何將兩者結合起來以獲得最大的名單到最少的名單,如果他們有相同的字母數訂購。如何結合兩個Collections.sort函數

Collections.sort(oneName, new OneNameCompare()); 
    for(OneName a: oneName) 
    { 
    System.out.println(a.toString()); 

    } 
Collections.sort(oneName, new OneNameCountCompare()); 
    for(OneName a: oneName) 
    { 

    System.out.println(a.toString()); 
    } 

回答

5

你可以再拍Comparator,結合其他兩個Comparator S的影響。如果一個比較器比較相等,則可以調用第二個比較器並使用其值。

public class CountNameComparator implements Comparator<Name> 
{ 
    private OneNameCompare c1 = new OneNameCompare(); 
    private OneNameCountCompare c2 = new OneNameCountCompare(); 
    @Override 
    public int compare(Name n1, Name n2) 
    { 
     int comp = c1.compare(n1, n2); 
     if (comp != 0) return comp; 
     return c2.compare(n1, n2); 
    } 
} 

然後您可以撥打Collections.sort一次。

Collections.sort(oneName, new CountNameComparator()); 

這可以推廣到任何數量的比較器。

2

您可以結合比較喜歡這個

public static <T> Comparator<T> combine(final Comparator<T> c1, final Comparator<T> c2) { 
    return new Comparator<T>() { 
     public int compare(T t1, T t2) { 
      int cmp = c1.compare(t1, t2); 
      if (cmp == 0) 
       cmp = c2.compare(t1, t2); 
      return cmp; 
     } 
    }; 
} 

BTW比較是當使用無狀態的單身一個很好的例子。所有的比較器或類型都是相同的,所以你只需要其中的一個。

public enum OneNameCompare implements Comparator<OneName> { 
    INSTANCE; 
    public int compare(OneName o1, OneName o2) { 
     int cmp = // compare the two objects 
     return cmp; 
    } 
} 

這可以避免創建新的實例或緩存副本。你只需要每種類型中的一種。

1

假設你正在使用Apache Commons Collections中的API,你可能想看看ComparatorUtils.chainedComparator

Collections.sort(oneName, ComparatorUtils.chainedComparator(new OneNameCompare(), new OneNameCountCompare()); 
0

使用lambda表達式從Java 8:

Collections.sort(Arrays.asList(""), 
     (e1, e2) -> e1.getName().compareTo(e2.getName()) != 0 ? 
       e1.getName().compareTo(e2.getName()) : 
       e1.getCount().compareTo(e2.getCount()));