我有一个程序,我有一个名单列表,以及有多少人拥有该名称。我想按字母顺序排列名称,同时将计数从最大到最小。如果名称具有相同的计数,则将名称按字母顺序排列。我想出了如何将名称放在abc顺序中,并想出如何将计数放在最小到最小但我无法弄清楚如何将两者结合起来获得最大和最小的名称列表,如果它们具有相同的字母数顺序。
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());
}
答案 0 :(得分:5)
你可以制作另一个Comparator
,它结合了另外两个Comparator
的效果。如果一个比较器比较相等,则可以调用第二个比较器并使用其值。
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());
这可以推广到任意数量的比较器。
答案 1 :(得分: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;
}
}
这可以避免创建新实例或缓存副本。你只需要每种类型中的一种。
答案 2 :(得分:1)
假设您正在使用Apache Commons Collections API,您可能需要查看ComparatorUtils.chainedComparator
:
Collections.sort(oneName, ComparatorUtils.chainedComparator(new OneNameCompare(), new OneNameCountCompare());
答案 3 :(得分:0)
使用Java 8中的lambdas:
Collections.sort(Arrays.asList(""),
(e1, e2) -> e1.getName().compareTo(e2.getName()) != 0 ?
e1.getName().compareTo(e2.getName()) :
e1.getCount().compareTo(e2.getCount()));