Java lambda在排序时抛出NPE

Nex*_*nts 1 java sorting lambda comparator java-stream

我有以下代码:

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());
    }
Run Code Online (Sandbox Code Playgroud)

有了这个,我的目标是进行两种排序,第一种是根据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
Run Code Online (Sandbox Code Playgroud)

两种排序后的预期结果:

NavCatModel priority : 200 , NOT NULL reserveStockRuleSet
NavCatModel priority : 100 , NOT NULL reserveStockRuleSet
NavCatModel priority : 500 , null reserveStockRuleSet
NavCatModel priority : 300 , null reserveStockRuleSet
Run Code Online (Sandbox Code Playgroud)

如何修改此 lambda 以实现此输入/输出示例?

use*_*er7 6

通过.sorted对流进行两次调用,您不会链接两个比较器。最后一个简单地赢了。您需要为此使用thenComparing

Comparator.nullsLast当 mapper 函数将元素映射到 null 时起作用。当映射器抛出 NPE 时它不起作用。

换句话说,在navigationCategoryModel.getReserveStockRuleSet().getCode(),如果getCode()返回null ,它将起作用;不是在getReserveStockRuleSet返回空值时。您必须在计算中明确检查 null。

.sorted(Comparator.comparing(NavigationCategoryModel::getReserveStockRuleSetCategoryPriority, 
                    Comparator.reverseOrder())
                    .thenComparing(navigationCategoryModel -> 
                                    navigationCategoryModel.getReserveStockRuleSet() != null 
                                            ? navigationCategoryModel.getReserveStockRuleSet().getCode() 
                                            : null, 
                            Comparator.nullsLast(Comparator.naturalOrder())))
Run Code Online (Sandbox Code Playgroud)

注意:Comparator.nullsLast(..)假设第一个比较器是原始 int 并且不能为 null,我已将其删除。