java 正在为List〈List>创建通用比较器< Comparable>

ssgvzors  于 2023-01-01  发布在  Java
关注(0)|答案(1)|浏览(140)

我正在尝试为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并不改变现有的比较器,而是返回一个新的比较器。

cetgtptt

cetgtptt1#

正如 @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);
}

相关问题