为何List<List<Comparable>>通用多列比较器仅首字段生效?如何修复?
多列排序Comparator仅第一个字段生效的问题解决
要实现对List<List<Comparable>>(代表行数据列表)的多列排序,编写的sort方法仅第一个指定排序字段生效,后续字段的排序逻辑完全不生效——比如按[0,1]排序时只有列0排序正确,列1无作用;按[1,0]排序时只有列1生效。
原问题代码
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); }
问题根源
Java的Comparator.thenComparing()方法是不可变操作:它不会修改调用该方法的原Comparator对象,而是返回一个新的、包含了后续比较逻辑的Comparator实例。原代码中只是调用了该方法但没有将返回值重新赋值给comparator变量,导致后续的比较逻辑从未被组合到最终的排序比较器中,始终只有第一个字段的比较器在工作。
修复后的代码
只需要将thenComparing的返回值重新赋值给comparator即可:
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 = comparator.thenComparing(listComparator); } } data.sort(comparator); }
内容的提问来源于stack exchange,提问作者Peter Kronenberg
相关产品推荐
相关产品推荐

