Java Comparator.nullsLast与Comparator.comparingInt
我有一个比较整数(可以为空)的比较器,所以 我尝试使用Java Comparator.nullsLast与Comparator.comparingInt,java,Java,我有一个比较整数(可以为空)的比较器,所以 我尝试使用比较器。comparingit,但它不起作用: public static final Comparator<Task> sort = Comparator.comparingInt(x -> x.getNumber(), Comparator.nullsLast(null)); 但我想知道为什么,因为我想比较整数,所以compareInt是正确的选择 如何将Compar
比较器。comparingit
,但它不起作用:
public static final Comparator<Task> sort =
Comparator.comparingInt(x -> x.getNumber(),
Comparator.nullsLast(null));
但我想知道为什么,因为我想比较整数,所以compareInt是正确的选择
如何将Comparator.nullsLast
与Comparator.comparingit
结合使用
Integer
和int
不一样。特别是,任何比较int的尝试都无法处理null
,您在这里确实需要它,所以它是正确的。使用比较
comparingit
方法,该方法只接受一个参数:一个lambda,它将给定的任务
转换为int
。这不是使用nullsLast
的方式任务
中提取一个整数
,然后使用nullsLast
比较器实现排序。这意味着空值将是最后一个,是的,,并且所有其他整数将以任意顺序排列。正如我所说,这不是使用nullsLast
的方式nullsLast
:
案例:您的任务列表包含null而不是任务:
someListOfTasks.sort(Comparator.nullsLast(Comparator.comparating(task::getNumber))代码>
案例:任务列表中包含一个数字为null的任务:
someListOfTasks.sort(Comparator.comparing(任务::getNumber,Comparator.nullsLast(Comparator.naturalOrder()))代码>
(我想这就是你想要的)
案例:您的任务列表既包含null而不是tasks,也包含一些数字为null的任务:
someListOfTasks.sort(Comparator.nullsLast(Comparator.comparating(task::getNumber,Comparator.nullsLast(Comparator.naturalOrder())))代码>
这可能会让人觉得有些罗嗦,但请注意,一个null与另一个null没有关系,您可能希望null任务条目首先排序,而带有null数字的非null任务最后排序。您的问题中没有任何内容表明您的列表中有空任务,因此您需要第二个示例
那么这意味着什么呢?
Comparator.comparing(valueExtractor,valueComparator)
是通用语法。您可以省略valueComparator
部分,在这种情况下,您将获得所谓的“自然排序”。对于整数,它是0,1,2,3,4….
——显而易见的一个。对于随机对象,如果它们实现了Comparable
(java.lang.Integer
实现了这一点),那么将实现您尝试排序的对象的compareTo
方法
请注意,根据定义,自然顺序不能处理null(毕竟,尝试在null上调用compareTo
与在任何null ref上调用任何实例方法所做的相同:它抛出NullPointerException
)。您可以通过不使用自然顺序,而是使用nullsFirst或nullsLast比较器来“修复”该问题。这些“包装”是一个比较器,因此语法为:
Comparator.nullsLast(comparatorToWrap)
这意味着:首先,将所有空值排序到底。然后,要比较所有非空条目,请使用comparatorToWrap
。在您发布的代码片段中,您已在此处为comparatorToWrap
传入了null
。nullsLast
的规范明确指出:这意味着所有非空值都被认为是相等的,这意味着,如果排序列表、任意顺序,对于映射/集,只有一个非空键:任意一种方式,而不是您想要的。显然,您希望具有非空数字的任务按照整数的自然顺序进行排序,即具有数字“1”的任务的排序应高于具有数字“2”的任务的排序。因此,传入自然顺序比较器:comparator.nullslat(comparator.naturalOrder())
——这意味着:首先将所有null排序到底,然后根据此处的自然顺序对其余的进行排序
然后,您希望将此概念(“最后排序为null,其余按自然顺序排序”)应用于任务本身,而不是应用于task.getNumber()
返回的任何内容,因此,我们首先需要一个lambda来提取(因此,task::getNumber
或x->x.getNumber()
,它们的含义相同),然后我们传入整数
比较器以启动:
Comparator sortIntegersNaturallyWithNullsLast=Comparator.nullsLast(Comparator.naturalOrder());
函数extractNumber=Task::getNumber;
排序(Comparator.comparing(extractNumber,sortIntegersNaturallyWithNullsLast));
注意:另一种选择是使任务具有自然顺序:
公共类任务实现可比较{
私有整数;
…这里的其他同学。。
@覆盖公共整数比较(任务其他){
整数o=其他数字;
if(number==null&&o==null)返回0;
如果(number!=null)返回-1;
如果(o!=null)返回+1;
返回编号。与(o)比较;
}
}
然后您可以使用Comparator.naturalOrder()
:listOfTasks.sort(Comparator.naturalOrder())
comparingit
用于返回int
的方法,而不是Integer
。您应该使用比较
。从什么时候开始比较
接受两个参数?有没有办法将空值设置
与比较
结合使用?例如,nullsLast(comparingit(x->x.getNumber())
也不起作用。nullsLast(comparing(x->x.getNumber())
起作用吗?@nimo23好吧,我误解了。你为什么不喜欢你发现有效的解决方案<代码>比较器。比较(x->x.getNumber(),
The method comparingInt(ToIntFunction<? super T>)
in the type Comparator is not applicable for
the arguments ((<no type> x) -> {}, Comparator.nullsLast(null))
public static final Comparator<Task> sort =
Comparator.comparing(x -> x.getNumber(),
Comparator.nullsLast(null));