我有一个比较整数(可以为空)的比较器,所以
我尝试使用Comparator.comparingInt,但它不起作用:
public static final Comparator<Task> sort =
Comparator.comparingInt(x -> x.getNumber(),
Comparator.nullsLast(null));
Run Code Online (Sandbox Code Playgroud)
我收到编译器错误:
The method comparingInt(ToIntFunction<? super T>)
in the type Comparator is not applicable for
the arguments ((<no type> x) -> {}, Comparator.nullsLast(null))
Run Code Online (Sandbox Code Playgroud)
当使用comparing而不是 时comparingInt,它可以工作:
public static final Comparator<Task> sort =
Comparator.comparing(x -> x.getNumber(),
Comparator.nullsLast(null));
Run Code Online (Sandbox Code Playgroud)
但我想知道为什么因为我想比较整数所以compareInt将是正确的选择。
如何Comparator.nullsLast与 ? 结合 使用Comparator.comparingInt?
Integer并且int不一样。特别是,任何比较 int 的尝试都无法处理null,而您在这里确实需要,所以它是正确的。使用comparing。
您的第一个代码片段不起作用,因为您将 2 个参数传递给该方法,该方法只需要一个:将给定转换为comparingInt的 lambda 。这不是你使用的方式。TaskintnullsLast
您的第二个代码片段确实有效,但它做了完全不同的事情:它首先Integer从您的 中提取 an Task,然后使用nullsLast比较器实现排序。这意味着空值将是最后一个,是的,并且所有其他整数将按任意顺序排列。正如我所说,这不是你使用的方式nullsLast。
这就是你的使用方式nullsLast:
someListOfTasks.sort(Comparator.nullsLast(Comparator.comparing(task::getNumber)));
someListOfTasks.sort(Comparator.comparing(task::getNumber, Comparator.nullsLast(Comparator.naturalOrder())));
(我想这就是你想要的)
\n\nsomeListOfTasks.sort(Comparator.nullsLast(Comparator.comparing(task::getNumber, Comparator.nullsLast(Comparator.naturalOrder()))));
这可能感觉相当冗长,但请注意,一个 null 与另一个 null 没有关系,并且您很可能希望 null 任务条目首先排序,而具有 null 数字的非 null 任务最后排序。您的问题中没有任何内容表明您的列表中有空任务,因此您需要第二个示例。
\n\nComparator.comparing(valueExtractor, valueComparator)是一般语法。您可以省略该valueComparator部分,在这种情况下您将得到所谓的“自然排序”。对于 Integer,0,1,2,3,4....最明显的是 \xe2\x80\x93。对于随机对象,如果它们实现了Comparable(确实java.lang.Integer如此),那么compareTo您尝试排序的对象的方法就会被实现。
请注意,根据定义,自然顺序无法处理 null(毕竟,尝试调用compareTonull 会执行与调用任何 null 引用上的任何实例方法相同的操作:它会抛出NullPointerException)。您可以通过不使用自然顺序而是使用 nullsFirst 或 nullsLast 比较器来“修复”该问题。这些“包装”比较器,因此语法是:
Comparator.nullsLast(comparatorToWrap)
这意味着:首先,将所有空值排序到最后。然后,要比较所有非空条目,请使用comparatorToWrap。在您发布的代码片段中,您已进入null此处comparatorToWrap。规范nullsLast明确指出:这意味着所有非空值都被视为相等,这意味着,如果对列表进行排序、任意顺序,并且对于映射/集,只有 1 个非空键:无论哪种方式,都不是您想要的。您显然希望具有非空数字的任务根据整数的自然顺序进行排序,即具有数字“1”的任务应该比具有数字“2”的任务排序更高。因此,传入自然顺序比较器:Comparator.nullsLast(Comparator.naturalOrder())\xe2\x80\x93 这意味着:首先将所有空值排序到最后,然后根据此处的自然顺序对其余部分进行排序。
然后,您希望将这个概念(“最后排序空值,其余按自然顺序排序”)应用到任务本身,而不是应用到任何task.getNumber()返回值,因此我们首先需要一个 lambda 来提取 (so, Task::getNumberor x -> x.getNumber(); 这些意味着同样的事情),然后我们传入Integer比较器来启动:
Comparator<Integer> sortIntegersNaturallyWithNullsLast = Comparator.nullsLast(Comparator.naturalOrder());\n\nFunction<Task, Integer> extractNumber = Task::getNumber;\n\nlistOfTasks.sort(Comparator.comparing(extractNumber, sortIntegersNaturallyWithNullsLast));\nRun Code Online (Sandbox Code Playgroud)\n\n注意:另一种选择是让任务具有自然顺序:
\n\npublic class Task implements Comparable<Task> {\n private Integer number;\n .. rest of class here ..\n\n @Override public int compareTo(Task other) {\n Integer o = other.number;\n if (number == null && o == null) return 0;\n if (number != null) return -1;\n if (o != null) return +1;\n return number.compareTo(o);\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n\n然后你就可以用Comparator.naturalOrder(): listOfTasks.sort(Comparator.naturalOrder())。
| 归档时间: |
|
| 查看次数: |
2639 次 |
| 最近记录: |