【问题标题】:Comparator.comparing().reversed() reverses all the earlier comparators?Comparator.comparing().reversed() 反转所有早期的比较器?
【发布时间】:2019-12-29 09:21:22
【问题描述】:

我有一个 Triple 列表,它是一个用户定义的类。当我使用Comparator 对其进行排序时,它显示出奇怪的行为。

考虑一下这个 sn-p -

List<Triple> list = new ArrayList<>();
list.add(new Triple(1,12,13)); //adding values to list
list.add(new Triple(11,3,31));
list.add(new Triple(16,6,32));
list.add(new Triple(16,8,32));
list.add(new Triple(16,7,32));
list.add(new Triple(16,9,32));
list.add(new Triple(16,5,32));
list.add(new Triple(7,21,0));
list.add(new Triple(6,22,12));
list.add(new Triple(4,22,13));
list.add(new Triple(2,77,3));
list.add(new Triple(1,8,30));

使用比较器排序

 list.sort(
 Comparator.comparingInt(Triple::getA)
.thenComparingInt(Triple::getB)
.thenComparing(Triple::getC));
 list.forEach(e->System.out.printf("(%d,%d,%d) ",e.getA(),e.getB(),e.getC()));
 System.out.println();
//sort A descending if for same A ascending B and for same B ascending C
 list.sort(
Comparator.comparingInt(Triple::getA).reversed()
.thenComparingInt(Triple::getB)
.thenComparing(Triple::getC));
 list.forEach(e->System.out.printf("(%d,%d,%d) ",e.getA(),e.getB(),e.getC()));
 System.out.println();
//sort A ascending if for same A descending B and for same B ascending C
list.sort(
Comparator.comparingInt(Triple::getA)
.thenComparingInt(Triple::getB)
.reversed()
.thenComparing(Triple::getC));
list.forEach(e->System.out.printf("(%d,%d,%d) ",e.getA(),e.getB(),e.getC()));
System.out.println();
//sort A ascending if for same A ascending B and for same B descending C
list.sort(
Comparator.comparingInt(Triple::getA)
.thenComparingInt(Triple::getB)
.thenComparing(Triple::getC)
.reversed());
list.forEach(e->System.out.printf("(%d,%d,%d) ",e.getA(),e.getB(),e.getC()));

我希望输出是我在 cmets 中所述的列表 -

但是输出是


(16,5,32) (16,6,32) (16,7,32) (16,8,32) (16,9,32) (11,3,31) (7,21,0) (6,22,12) (4,22,13) (2,77,3) (1,8,30) (1,12,13)

(16,9,32) (16,8,32) (16,7,32) (16,6,32) (16,5,32) (11,3,31) (7,21,0) (6,22,12) (4,22,13) (2,77,3) (1,12,13) (1,8,30)

(16,9,32) (16,8,32) (16,7,32) (16,6,32) (16,5,32) (11,3,31) (7,21,0) (6,22,12) (4,22,13) (2,77,3) (1,12,13) (1,8,30)

因此 reversed() 方法反转了之前的比较器条件。

供您参考,Triple 只是具有三个变量和获取设置方法的类。

【问题讨论】:

  • 当然。 thenComparing() 返回一个比较器。这个比较器定义了一个顺序。并且 .reversed() 返回另一个比较器,定义应用它的比较器的相反顺序。
  • 如果你只想反转链的最后一个比较器,那么只反转那个比较器:thenComparing(Comparator.comparing(Triple::getC).reversed())

标签: java list sorting comparator


【解决方案1】:

由于您定义了像Comparator.comparingInt(Triple::getA) .thenComparingInt(Triple::getB) 这样的比较器,这将返回一个新的Comparator 对象,其中包含之前比较对象的两种方式。如果您随后在此 Comparator 上调用 reversed,它会返回新的 Comparator 来反转此 Comparator - 因此在这种情况下,之前的两个条件都将被反转。

如果您想反转链中的比较器之一,您可以使用类似:

.thenComparing(Triple::getB, Comparator.reverseOrder())

所以你的比较器之一可能看起来像:

Comparator.comparingInt(Triple::getA)
                        .thenComparing(Triple::getB, Comparator.reverseOrder())
                        .thenComparing(Triple::getC)

这只会反转 B 属性的排序条件。

【讨论】:

  • 非常有帮助 @michalk 我曾经这样做过 Comparator.comparing(Triple::getA).reversed().thenComparing(Triple::getB).reversed() 谢谢
猜你喜欢
  • 1970-01-01
  • 2019-10-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-04
相关资源
最近更新 更多