使用 java 8 流处理空属性并使用 lambda 表达式进行排序

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/31284282/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 18:23:08  来源:igfitidea点击:

Dealing with a null attribute using java 8 streams and sorting using lambda expressions

javanullpointerexceptionjava-8

提问by Manu Joy

Let's consider a Parentclass which contains only one Integerattribute. I created 6 objects of parent class and values of attribute are 100, 20, 300, 400, 500, null.

让我们考虑一个Parent只包含一个Integer属性的类。我创建了 6 个父类对象,属性值是100, 20, 300, 400, 500, null.

Now I added all the objects to a list(Name of list is list). Then I want to get the objects whose attribute value is greater than 100. I used Java 8 streams for this purpose.

现在我将所有对象添加到列表中(列表名称为列表)。然后我想获取属性值大于 的对象100。为此,我使用了 Java 8 流。

Predicate<Entity> predicate = e -> e.getParentId() < 100;
result = list.stream().filter(predicate).collect(Collectors.toList());

I also want to sort the list in descending order. I used the following code for this purpose.

我还想按降序对列表进行排序。为此,我使用了以下代码。

Comparator<Entity> comp = (d1,d2) -> d2.getId().compareTo(d1.getId());
list.sort(comp);

In both cases I get a NullPointerException.

在这两种情况下,我都会得到一个NullPointerException.

How to handle this?

如何处理?

回答by Brian Goetz

All of the answers here revolve around "throw out the bad elements, those that have a null getParentId()." That may be the answer, if they are indeed bad. But there's another alternative: Comparators.nullsFirst(or last.) This allows you to compare things treating a null value as being less than (or greater than) all non-null values, so you don't have to throw the elements with a null parentId away.

这里的所有答案都围绕着“扔掉坏元素,那些有 null 的元素getParentId()”。如果它们确实很糟糕,那可能就是答案。但是还有另一种选择:(Comparators.nullsFirst或最后一个。)这允许您比较将空值视为小于(或大于)所有非空值的事物,因此您不必将具有空 parentId 的元素扔掉.

Comparator<Entity> cmp = nullsLast(comparing(Entity::getParentId));
List<Entity> list = list.stream().sorted(cmp).collect(toList());

You can do a similar thing for filtering; define your predicate as:

您可以为过滤做类似的事情;将谓词定义为:

Predicate<Entity> predicate = e -> e.getParentId() != null 
                                       && e.getParentId() < 100;

回答by joetde

Looks like you are looking for something like:

看起来你正在寻找类似的东西:

list.sort(Comparator.comparing(Entity::getParent, 
                               Comparator.nullsLast(Integer::compareTo)));

All the elements with parent null will be put at the end and the rest will be sorted by their parent.

所有父元素为 null 的元素将放在最后,其余元素将按其父元素排序。

回答by Dominik Sandjaja

Try pre-filtering for non-null parentIdvalues only:

尝试parentId仅对非空值进行预过滤:

result = list.stream().filter(e -> e.getParentId() != null).filter(predicate).collect(Collectors.toList());

[edit] Just saw, that the attribute (e.parentId) seems the one being null. In that case, the second thing, the sorting, breaks. You are sorting the original list, not the filtered one. Try result.sort(comp), then you should avoid the NPE.

[编辑] 刚刚看到,属性 ( e.parentId) 似乎是null. 在这种情况下,第二件事,排序,中断了。您正在对原始列表进行排序,而不是过滤后的列表。尝试result.sort(comp),那么您应该避免使用 NPE。

回答by Eran

You can do it all in one Stream pipeline :

您可以在一个 Stream 管道中完成所有操作:

List<Entity> result =  
    list.stream()
        .filter(e -> e.getParentId()!=null) // it's not clear if the null
                                            // is the Entity object itself
                                            // (in which case it should be e!=null)
                                            // or just the ParentId member
        .filter(predicate)
        .sorted(comp)
        .collect(Collectors.toList());

BTW, according to the text of your question, the original predicate should be :

顺便说一句,根据你的问题的文字,原来的谓词应该是:

Predicate<Entity> predicate = e -> e.getParentId() > 100; // not < 100

回答by Fritz Duchardt

Harness the power of a method referenceto make the code even more compact:

利用方法引用的强大功能使代码更加紧凑:

   List<Entity> result =
            list.stream()
                    .filter(Objects::nonNull) 
                    .filter(predicate)
                    .sorted(comp)
                    .collect(Collectors.toList());

回答by Konstantin Yovkov

You can do:

你可以做:

Predicate<Entity> predicate = e -> e.getParentId() < 100;
Predicate<Entity> nonNull = e -> e != null;
result = list.stream().filter(nonNull)
                      .filter(predicate)
                      .collect(Collectors.toList());

Of course, you could combinethe predicates into one, but I introduced a second one for better readability. Also, you're free to change the nonNullpredicate to check either the whole entity, or just the idattribute (or even both). Just play a bit with it. :)

当然,您可以谓词合二为一,但为了更好的可读性,我引入了第二个谓词。此外,您可以自由更改nonNull谓词以检查整个实体,或仅检查id属性(甚至两者)。只是玩一下。:)