我正在编写自己的比较器类PercentComparator
,并按以下方式调用排序
Collections.sort(engineList, new PercentageComparator());
其中engineList
是对象列表,其中每个对象具有百分比完整值,并且上面的排序功能正常工作。
现在,客户要求按产品类型和百分比按元素添加另一个订单。我们可以通过对象的两个元素来排序吗?
答案 0 :(得分:4)
Collections.sort(engineList, new PercentageComparator());
Collections.sort(engineList, new ProductTypeComparator());
按产品类型和相同产品类型排序按百分比进一步排序。这是因为
此类保证稳定:由于排序,相同的元素不会被重新排序。
http://docs.oracle.com/javase/6/docs/api/java/util/Collections.html#sort%28java.util.List%29
答案 1 :(得分:3)
创建您自己的新Comparator,在比较产品类型后调用Percentage Comparator。
答案 2 :(得分:1)
如果我做对了:
class EngineComparator implements Comparator<Engine> {
@Override
public int compare(Engine o1, Engine o2) {
int result = o1.getProdType().compareTo(o2.getProdType());
return (result == 0) ? o1.getPercent().compareTo(o2.getPercent()) : result;
}
}
以下是对集合进行分类的方法:
Prod-Type Percent ======================= A 1 A 2 A 3 B 1 B 2 B 3 C 1 C 2 C 3
答案 3 :(得分:0)
如果要进行单独分类,请做一个单独的比较并在链中使用它们。或者你的EngineComparator(Boolean sortPercentDesc, Boolean sortProductDesc)
,我认为可能更好,更容易维护。
答案 4 :(得分:0)
只要所有相关(可比较)信息都包含在传递给方法的对象中,您的排序方法就可以进行任何您想要的排序。换句话说,您的可排序对象应包含所有可排序的子字段。而且你必须用一种不同的排序方法/类来处理它。
答案 5 :(得分:0)
如果第一个比较器返回0
,您可以创建一个具有两个比较器的复合比较器,并从第二个比较器返回值。
您甚至可以使用N个比较器列表展开此过程并返回第一个非零结果,或者如果到达列表末尾则返回0
。
答案 6 :(得分:0)
通常,您的比较器会一次测试一个字段,直到存在差异。例如,如果百分比优先,后跟产品类型,并且您的类具有聪明的名称StackOverflow1:
Comparator<StackOverflow1> COMPARATOR = new Comparator<StackOverflow1>() {
@Override
public int compare(StackOverflow1 o1, StackOverflow1 o2) {
int result = Double.compare(o1.percent, o2.percent);
if (result == 0)
result = o1.productType - o2.productType;
// NOTE - above line isn't really safe but used for illustration...
// any more tests of fields here...
return result;
}
};
如果你想要大量的灵活性,一定要写出一堆独立的比较器并将它们连在一起(正如其他人所建议的那样),但很多时候都是过度杀戮 - 你只需要一个。
答案 7 :(得分:0)
首先创建另一个比较器实现,仅比较产品类型。然后打电话给:
Collections.sort(engineList, new CompoundComparator(productTypeCmp, percentageCmp));
以下是复合比较器的实现,它按照传入的顺序将比较委托给传入的比较器。
class CompoundComparator implements Comparator<Engine>{
private List<Comparator> comparators;
public CompoundComparator(Comparator<Engine> ... comparators){
this.comparators = Arrays.asList(comparators);
}
public int compare(Engine o1, Engine o2){
int cmp = 0;
Iterator cmpIter = comparators.iterator();
while(cmp == 0 && cmpIter.hasNext()){
cmp = cmpIter.next().compare(o1, o2);
}
return cmp;
}
}
假设对象属于Engine类型。
答案 8 :(得分:0)
要获得更通用的解决方案,请查看来自Javadocs的Apache Common的ComparatorChain:
ComparatorChain是一个比较器,它按顺序包装一个或多个比较器。 ComparatorChain按顺序调用每个Comparator,直到1)任何单个Comparator返回非零结果(然后返回该结果),或2)ComparatorChain耗尽(并返回零)。这种类型的排序与SQL中的多列排序非常相似,这个类允许Java类在排序List时模拟这种行为。