我有一个比较器比较Integer (可以是null),所以
我试着使用Comparator.comparingInt,但它不起作用:
public static final Comparator<Task> sort =
Comparator.comparingInt(x -> x.getNumber(),
Comparator.nullsLast(null));我得到编译器错误:
The method comparingInt(ToIntFunction<? super T>)
in the type Comparator is not applicable for
the arguments ((<no type> x) -> {}, Comparator.nullsLast(null))当使用comparing而不是comparingInt时,它起作用:
public static final Comparator<Task> sort =
Comparator.comparing(x -> x.getNumber(),
Comparator.nullsLast(null));但是我想知道为什么,因为我想比较整数,所以compareInt是正确的选择。
如何将Comparator.nullsLast与Comparator.comparingInt结合使用?
发布于 2020-03-02 09:37:35
Integer和int不一样。特别是,任何比较int的尝试都无法处理null,这是您在这里确实需要的,所以它很快就会出现。使用comparing.comparingInt方法,该方法只需要一个:将给定的Task转换为int的lambda。这不是使用nullsLast.Task中提取一个Integer,然后使用nullsLast比较器实现排序。这意味着空值将是最后一个,是的,和所有其他整数都将是任意顺序的。就像我说的,这不是你使用nullsLast.的方式
这就是您如何使用nullsLast的方法
case:任务列表包含null,而不是任务:
someListOfTasks.sort(Comparator.nullsLast(Comparator.comparing(task::getNumber)));
case:您的任务列表包含一个数字为null的任务:
someListOfTasks.sort(Comparator.comparing(task::getNumber, Comparator.nullsLast(Comparator.naturalOrder())));
(我想这就是你想要的)
大小写:您的任务列表包含两个空值,而不是任务,有些任务的数字为null:
someListOfTasks.sort(Comparator.nullsLast(Comparator.comparing(task::getNumber, Comparator.nullsLast(Comparator.naturalOrder()))));
这可能有点冗长,但请注意,一个null与另一个null没有关系,您很可能希望空任务条目先排序,而非空任务的空号排序。您的问题中没有任何内容表明您的列表中有空任务,因此需要第二个示例。
那这是什么意思?
Comparator.comparing(valueExtractor, valueComparator)是通用语法。您可以省略valueComparator部分,在这种情况下,您将得到所谓的“自然排序”。对于Integer来说,这是0,1,2,3,4.... --显而易见的一个。对于随机对象,如果它们实现了Comparable ( java.lang.Integer这样做),那么您要排序的对象的compareTo方法就实现了。
注意,根据定义,自然顺序不能处理空(毕竟,尝试对null调用compareTo会执行调用任何null ref上的任何实例方法的相同操作:它会抛出NullPointerException)。您可以通过不使用自然顺序,而是使用nullsFirst或nullsLast比较器来“修复”这个问题。这些“包装”是一个比较器,因此语法是:
Comparator.nullsLast(comparatorToWrap)
这意味着:首先,将所有空值排序到末尾。然后,要比较所有非空项,请使用comparatorToWrap。在您发布的片段中,您在这里传递了null for comparatorToWrap。nullsLast的规范明确规定:这意味着所有非空值都被认为是相等的,这意味着,如果排序列表、任意顺序,对于映射/集,只有一个非空键:,不管是哪种方式,而不是您想要的。您显然希望非空数的任务按照整数的自然顺序排序,即数字'1‘的任务排序应该高于数字'2’的任务。因此,传递自然顺序比较器:Comparator.nullsLast(Comparator.naturalOrder()) -这意味着:首先排序所有的空到最后,然后排序其余的根据什么是自然在这里。
然后,您想要将这个概念(‘排序空最后,其余按自然顺序排列’)不应用于任务本身,而是应用于任何task.getNumber()返回的任务,因此我们首先需要一个提取(so、Task::getNumber或x -> x.getNumber();这些都意味着相同的事情)的lambda,然后传入我们的Integer比较器来引导:
Comparator<Integer> sortIntegersNaturallyWithNullsLast = Comparator.nullsLast(Comparator.naturalOrder());
Function<Task, Integer> extractNumber = Task::getNumber;
listOfTasks.sort(Comparator.comparing(extractNumber, sortIntegersNaturallyWithNullsLast));注:另一种选择是使任务具有自然的顺序:
public class Task implements Comparable<Task> {
private Integer number;
.. rest of class here ..
@Override public int compareTo(Task other) {
Integer o = other.number;
if (number == null && o == null) return 0;
if (number != null) return -1;
if (o != null) return +1;
return number.compareTo(o);
}
}然后您可以直接使用Comparator.naturalOrder():listOfTasks.sort(Comparator.naturalOrder())。
https://stackoverflow.com/questions/60485232
复制相似问题