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。