2014-09-29 74 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()));