【问题标题】:Java lambda throwing NPE when sorting排序时Java lambda抛出NPE
【发布时间】:2020-11-05 22:19:53
【问题描述】:

我有以下代码:

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 的 NavigationCategoryModel 放在列表的末尾。

但是,我得到了 NPE,因为在这个类别列表中,我可以接收带有属性 reserveStockRuleSet 为 null 的 NavigationCategoryModels。

我不想从排序中过滤和排除那些为空的,因为我想将它们放在列表的末尾

一个示例输入是:

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 以实现此输入/输出示例?

【问题讨论】:

  • 看看logicbig.com/how-to/code-snippets/…,因为调用.sorted 两次不会达到你想要的效果。此外,我猜想在 getter 上防止 null 可能是这样的:```.sorted(nullsFirst(comparing(Object::getSomething, nullsFirst(naturalOrder()))) .thenComparing(nullsFirst(comparing(Object::getSomething, nullsFirst) (naturalOrder())))))

标签: java sorting lambda java-stream comparator


【解决方案1】:

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

Comparator.nullsLast 在映射器函数将元素映射到 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())))

注意:我已经删除了第一个比较器的 Comparator.nullsLast(..),假设它是一个原始 int 并且不能为空。

【讨论】:

    猜你喜欢
    • 2022-01-12
    • 1970-01-01
    • 2021-01-19
    • 2018-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多