Comparator.compareBoolean() 和 Comparator.compare() 一样吗?

Comparator.compareBoolean() the same as Comparator.compare()?

这个怎么写

Comparator <Item> sort = (i1, i2) -> Boolean.compare(i2.isOpen(), i1.isOpen());

像这样(代码不起作用):

Comparator<Item> sort = Comparator.comparing(Item::isOpen).reversed();

比较方法没有 Comparator.comparingBool() 之类的东西。 Comparator.comparing returns int 而不是 "Item".

为什么不能这样写?

 Comparator<Item> sort = Comparator.comparing(Item::isOpen);

下面调用了Boolean.compareTo,这又和Boolean.compare

一样
public static int compare(boolean x, boolean y) {
    return (x == y) ? 0 : (x ? 1 : -1);
}

而这个:Comparator.comparing returns int and not "Item".毫无意义,Comparator.comparing必须return一个Comparator<T>;在你的情况下它正确 returns a Comparator<Item>.

使用键提取器参数进行比较:

Comparator<Item> comparator = 
    Comparator.comparing(Item::isOpen, Boolean::compare).reversed();

重载 comparingIntcomparingLongcomparingDouble 仅出于性能原因而存在。它们在语义上与未专门化的 comparing 方法相同,因此使用 comparing 而不是 comparingXXX 具有相同的结果,但可能有装箱开销,但实际影响取决于特定的执行环境。

boolean 值的情况下,我们可以预测开销可以忽略不计,因为方法 Boolean.valueOf 将始终 return Boolean.TRUEBoolean.FALSE 并且从不创建新实例,因此即使特定的 JVM 无法内联整个代码,它也不依赖于优化器中是否存在 Escape Analysis。

如您所知,反转比较器是通过在内部交换参数来实现的,就像您在 lambda 表达式中手动执行的那样。

请注意,仍然可以创建一个融合反转和未装箱比较的比较器,而无需重复 isOpen() 表达式:

Comparator<Item> sort = Comparator.comparingInt(i -> i.isOpen()? 0: 1);

但是,如前所述,它不太可能比 Comparator.comparing(Item::isOpen).reversed() 方法具有更高的性能。


但请注意,如果您有 boolean 排序标准并关心最高性能,您可以考虑用桶排序变体替换通用排序算法。例如

如果你有流,替换

List<Item> result = /* stream of Item */
    .sorted(Comparator.comparing(Item::isOpen).reversed())
    .collect(Collectors.toList());

Map<Boolean,List<Item>> map = /* stream of Item */
    .collect(Collectors.partitioningBy(Item::isOpen,
                                       Collectors.toCollection(ArrayList::new)));
List<Item> result = map.get(true);
result.addAll(map.get(false));

或者,如果您有 List,请替换

list.sort(Comparator.comparing(Item::isOpen).reversed());

ArrayList<Item> temp = new ArrayList<>(list.size());
list.removeIf(item -> !item.isOpen() && temp.add(item));
list.addAll(temp);

等等