[英]Creating generic comparator for List<List<Comparable>>
我正在尝试为List<List<Comparable>>
创建一个通用比较器,它可以对多个字段进行排序。 该结构表示一个行列表,在每一行中,我想对多列进行排序。
我有这个
public static void sort(List<List<Comparable>> data, int... sortColumns) {
System.out.println("Sorting on columns " + Arrays.toString(sortColumns));
Comparator<List<Comparable>> comparator = null;
for (int i : sortColumns) {
final Comparator<List<Comparable>> listComparator = (o1, o2) -> o1.get(i).compareTo(o2.get(i));
if (comparator == null) {
comparator = listComparator;
} else {
comparator.thenComparing(listComparator) ;
}
}
data.sort(comparator);
}
但它似乎只适用于第一个排序字段,而不适用于多个字段。
例如,这是按第 0 列正确排序的,但不是第 1 列
[[4, foo], [5, baz], [5, barf], [1, zed], [6, fizz], [2, baz], [1, baz]]
Sorting on columns [0, 1]
[[1, zed], [1, baz], [2, baz], [4, foo], [5, baz], [5, barf], [6, fizz]]
同样,它在第 1 列而不是第 0 列上正确排序
[[4, foo], [5, baz], [5, barf], [1, zed], [6, fizz], [2, baz], [1, baz]]
Sorting on columns [1, 0]
[[5, barf], [5, baz], [2, baz], [1, baz], [6, fizz], [4, foo], [1, zed]]
我在构建比较器时做错了什么吗? 特别是,使用thenComparing
问题是thenComparing
不会改变现有的比较器,而是返回一个新的比较器。 我将 else 中的行更改为comparator = comparator.thenComparing(listComparator);
它奏效了
正如@dan1st在评论中指出的那样,您没有存储调用Comparator.thenComparing()
生成的结果。
另外,请注意Comparable
接口是通用的,并且您在方法中使用了行类型的 Comparable。
您的方法可以通过以下方式重新实现:
public static <T extends Comparable<T>> void
sort(List<List<T>> data, int... sortColumns) {
Comparator<List<T>> comparator = Arrays.stream(sortColumns)
.mapToObj(i -> Comparator.<List<T>, T>comparing(list -> list.get(i)))
.reduce(Comparator::thenComparing)
.orElseThrow();
data.sort(comparator);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.