Java lambda 在排序时抛出 NPE
Java lambda throwing NPE when sorting
我有以下代码:
private List<CategoryModel> getReserveStockRuleMaxPriorityNavigationCategoryModel (Collection<CategoryModel> categoryModels){
return categoryModels.stream()
.map(NavigationCategoryModel.class::cast)
.sorted(Comparator.comparing(NavigationCategoryModel::getReserveStockRuleSetCategoryPriority, Comparator.nullsLast(Comparator.reverseOrder())))
.sorted(Comparator.comparing(navigationCategoryModel -> navigationCategoryModel.getReserveStockRuleSet().getCode(),Comparator.nullsLast(Comparator.naturalOrder())))
.collect(Collectors.toList());
}
有了这个,我的目标是进行两种排序,第一种是根据 reserveStockRuleSetCategoryPriority INT 进行反向排序,然后将属性 reserveStock.code 为 null 的 NavigationCategoryModel 放在列表的末尾。
但是,我遇到了 NPE,因为在此类别列表中,我可以接收 NavigationCategoryModels,其属性 reserveStockRuleSet 为 null。
我不想从排序中过滤和排除空值,因为我想将它们放在列表的末尾
示例输入为:
NavCatModel priority : 500 , null reserveStockRuleSet
NavCatModel priority : 100 , NOT NULL reserveStockRuleSet
NavCatModel priority : 300 , null reserveStockRuleSet
NavCatModel priority : 200 , NOT NULL reserveStockRuleSet
两种排序后的预期结果:
NavCatModel priority : 200 , NOT NULL reserveStockRuleSet
NavCatModel priority : 100 , NOT NULL reserveStockRuleSet
NavCatModel priority : 500 , null reserveStockRuleSet
NavCatModel priority : 300 , null reserveStockRuleSet
如何修改此 lambda 以实现此 inputs/outputs 示例?
通过对流进行两次 .sorted
调用,您不会链接两个比较器。最后一个简单地赢了。您需要为此使用 thenComparing
。
Comparator.nullsLast
在映射器函数将元素映射到 null 时起作用。当映射器抛出 NPE 时它不起作用。
换句话说,在navigationCategoryModel.getReserveStockRuleSet().getCode()
中,如果getCode()
returns null,则有效;不是当 getReserveStockRuleSet
returns 为 null 时。您必须在计算中显式检查 null。
.sorted(Comparator.comparing(NavigationCategoryModel::getReserveStockRuleSetCategoryPriority,
Comparator.reverseOrder())
.thenComparing(navigationCategoryModel ->
navigationCategoryModel.getReserveStockRuleSet() != null
? navigationCategoryModel.getReserveStockRuleSet().getCode()
: null,
Comparator.nullsLast(Comparator.naturalOrder())))
注意:我已经删除了第一个比较器的 Comparator.nullsLast(..)
,假设它是原始 int 并且不能为 null。
我有以下代码:
private List<CategoryModel> getReserveStockRuleMaxPriorityNavigationCategoryModel (Collection<CategoryModel> categoryModels){
return categoryModels.stream()
.map(NavigationCategoryModel.class::cast)
.sorted(Comparator.comparing(NavigationCategoryModel::getReserveStockRuleSetCategoryPriority, Comparator.nullsLast(Comparator.reverseOrder())))
.sorted(Comparator.comparing(navigationCategoryModel -> navigationCategoryModel.getReserveStockRuleSet().getCode(),Comparator.nullsLast(Comparator.naturalOrder())))
.collect(Collectors.toList());
}
有了这个,我的目标是进行两种排序,第一种是根据 reserveStockRuleSetCategoryPriority INT 进行反向排序,然后将属性 reserveStock.code 为 null 的 NavigationCategoryModel 放在列表的末尾。
但是,我遇到了 NPE,因为在此类别列表中,我可以接收 NavigationCategoryModels,其属性 reserveStockRuleSet 为 null。
我不想从排序中过滤和排除空值,因为我想将它们放在列表的末尾
示例输入为:
NavCatModel priority : 500 , null reserveStockRuleSet
NavCatModel priority : 100 , NOT NULL reserveStockRuleSet
NavCatModel priority : 300 , null reserveStockRuleSet
NavCatModel priority : 200 , NOT NULL reserveStockRuleSet
两种排序后的预期结果:
NavCatModel priority : 200 , NOT NULL reserveStockRuleSet
NavCatModel priority : 100 , NOT NULL reserveStockRuleSet
NavCatModel priority : 500 , null reserveStockRuleSet
NavCatModel priority : 300 , null reserveStockRuleSet
如何修改此 lambda 以实现此 inputs/outputs 示例?
通过对流进行两次 .sorted
调用,您不会链接两个比较器。最后一个简单地赢了。您需要为此使用 thenComparing
。
Comparator.nullsLast
在映射器函数将元素映射到 null 时起作用。当映射器抛出 NPE 时它不起作用。
换句话说,在navigationCategoryModel.getReserveStockRuleSet().getCode()
中,如果getCode()
returns null,则有效;不是当 getReserveStockRuleSet
returns 为 null 时。您必须在计算中显式检查 null。
.sorted(Comparator.comparing(NavigationCategoryModel::getReserveStockRuleSetCategoryPriority,
Comparator.reverseOrder())
.thenComparing(navigationCategoryModel ->
navigationCategoryModel.getReserveStockRuleSet() != null
? navigationCategoryModel.getReserveStockRuleSet().getCode()
: null,
Comparator.nullsLast(Comparator.naturalOrder())))
注意:我已经删除了第一个比较器的 Comparator.nullsLast(..)
,假设它是原始 int 并且不能为 null。