Java 用番石榴排序法对对象列表进行多准则排序
我有一个类不能实现comparable,但需要根据两个字段进行排序。我怎样才能用番石榴做到这一点 让我们假设课程是:Java 用番石榴排序法对对象列表进行多准则排序,java,sorting,gwt,guava,Java,Sorting,Gwt,Guava,我有一个类不能实现comparable,但需要根据两个字段进行排序。我怎样才能用番石榴做到这一点 让我们假设课程是: class X { String stringValue; java.util.Date dateValue; } 我有一份清单: List<X> lotsOfX; 我的方法很有效,但是遍历列表两次显然效率很低。有更好的方法吗 我正在GWT应用程序中使用此功能。实施comparable不是一个选项。我想你是想要的。你可以在一个声明中完成这一切,但我会使用
class X {
String stringValue;
java.util.Date dateValue;
}
我有一份清单:
List<X> lotsOfX;
我的方法很有效,但是遍历列表两次显然效率很低。有更好的方法吗
我正在GWT应用程序中使用此功能。实施comparable不是一个选项。我想你是想要的。你可以在一个声明中完成这一切,但我会使用:
Ordering<X> primary = Ordering.natural().onResultOf(stringValueSortFunction);
Ordering<X> secondary = Ordering.natural()
.onResultOf(dateValueSortFunction)
.reverse();
Ordering<X> compound = primary.compound(secondary);
List<X> sortedList = compound.immutableSortedCopy(lotsOfX);
Ordering primary=Ordering.natural().onResultOf(stringValueSortFunction);
排序次要=排序.natural()
.onResultOf(dateValueSortFunction)
.reverse();
排序化合物=主要化合物(次要化合物);
List-sortedList=composite.immutableSortedCopy(lotsOfX);
一种功能性较差但可以说更干净的解决方案:
new Ordering<X>() {
public int compare(X x1, X x2) {
return ComparisonChain.start()
.compare(x1.stringValue, x2.stringValue)
.compare(x2.dateValue, x1.dateValue) // flipped for reverse order
.result();
}
}.immutableSortedCopy(listOfXs);
newordering(){
公共整数比较(X x1,X x2){
返回ComparisonChain.start()
.比较(x1.stringValue,x2.stringValue)
.compare(x2.dateValue,x1.dateValue)//按相反顺序翻转
.result();
}
}.immutableSortedCopy(listOfXs);
Java8提供了Comparator上的方法,以简洁地指定链式比较器。与新引入的List.sort一起,您可以执行以下操作:
lotsOfX.sort(
Comparator.comparingInt(x -> stringValueSortFunction.apply(x.stringValue))
.thenComparing(x -> x.dateValue, Comparator.reverseOrder()));
当然,这会改变列表——如果您想保持原始列表不变,请先复制一个副本;如果您想要一个不可变的副本,请按顺序包装比较器并使用
immutableSortedCopy
。我确实对此进行了研究,但我读到了。compare希望输入实现可比性。如果我理解正确,在这种情况下,它会按字母顺序对字符串排序?但是我需要加入我自己的自定义排序函数。如果你想使用自定义比较器对字符串进行排序,那么你可以使用比较(x1.stringValue,x2.stringValue,new MyCustomStringComparator())
。我明白了。好吧,只要其中一个表现不比另一个好,我两个都可以。我认为另一个答案是可以接受的。对于那些认为交换参数以获得反向顺序太微妙的人,你可以传入一个比较器作为第三个参数,并使用集合。reverseOrder()
,其内容如下:。compare(x1.dateValue,x2.dateValue,reverseOrder())
(假设您使用的是静态导入。天哪!谢谢您的帮助,为我节省了很多IF…ELSE案例!我正处于交叉条件的噩梦中。
Something 03/18/2013
Something 03/17/2013
Something else 03/20/2013
Something else 03/19/2013
....
Ordering<X> primary = Ordering.natural().onResultOf(stringValueSortFunction);
Ordering<X> secondary = Ordering.natural()
.onResultOf(dateValueSortFunction)
.reverse();
Ordering<X> compound = primary.compound(secondary);
List<X> sortedList = compound.immutableSortedCopy(lotsOfX);
new Ordering<X>() {
public int compare(X x1, X x2) {
return ComparisonChain.start()
.compare(x1.stringValue, x2.stringValue)
.compare(x2.dateValue, x1.dateValue) // flipped for reverse order
.result();
}
}.immutableSortedCopy(listOfXs);
lotsOfX.sort(
Comparator.comparingInt(x -> stringValueSortFunction.apply(x.stringValue))
.thenComparing(x -> x.dateValue, Comparator.reverseOrder()));