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.com partar返回int而不是"项目"。

为什么不能这样写?

 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 必须返回 Comparator<T>;在您的情况下,它正确返回了Comparator<Item>

仅出于性能原因而存在过载comparingIntcomparingLongcomparingDouble。它们在语义上与无专业化的comparing方法相同,因此使用comparing代替comparingXXX具有相同的结果,但可能在开销开销,但实际含义取决于特定的执行环境。

>

boolean值的情况下,我们可以预测间接费用可以忽略不计,因为方法Boolean.valueOf将始终返回Boolean.TRUEBoolean.FALSE,并且永远不会创建新实例,因此,即使特定的JVM未能在整个代码中内串联,也可以不取决于优化器中的逃生分析。

正如您已经知道的那样,逆转比较器是通过内部交换参数来实现的,就像您在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);

等。

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

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

最新更新