我该如何编写此
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>
。
仅出于性能原因而存在过载comparingInt
,comparingLong
和comparingDouble
。它们在语义上与无专业化的comparing
方法相同,因此使用comparing
代替comparingXXX
具有相同的结果,但可能在开销开销,但实际含义取决于特定的执行环境。
在boolean
值的情况下,我们可以预测间接费用可以忽略不计,因为方法Boolean.valueOf
将始终返回Boolean.TRUE
或Boolean.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();