17

Let's consider a Parent class which contains only one Integer attribute. I created 6 objects of parent class and values of attribute are 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.

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.

How to handle this?

2
  • 1
    possible duplicate of How should we manage jdk8 stream for null values Commented Jul 8, 2015 at 5:39
  • 2
    I'm unclear... is it e that is null, or e.getParentId()? If e.getParentId() is declared as an Integer (the boxed type), it may be null. But then when it's converted to an int to compare it to 100, the result will be a NullPointerException if it's null. Commented Jul 8, 2015 at 5:44

6 Answers 6

20

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.

Sign up to request clarification or add additional context in comments.

2 Comments

this solution worked for me. Because i don't want to filter null values.
Thanks for showing how to use Comparator.nullsLast.
19

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.

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;

1 Comment

I guess you meant Comparator.nullsFirst because Comparators is from Guava
7

Try pre-filtering for non-null parentId values only:

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.

2 Comments

This should work. You can also do .filter(Objects::nonNull)
The problem is object is not null, but the attribute is null,if my contains 100 attributes, and I created a list of that objects , in which many attribute may have null value in some of the objects in the list, how should i handle this.
4

You can do it all in one Stream pipeline :

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

3 Comments

Won't this filter e.getParentId() == null elements? He is talking about e being null.
@Codebender I may be misreading the question, but it seemed that OP created objects with parent IDs of 100,20,300,400,500,null, so I assumed the null referred to ParentId. I might be wrong.
@Codebender that's not clear. I think he's talking about the parentId being null, which is possible if it's an Integer.
2

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

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

Comments

1

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 combine the predicates into one, but I introduced a second one for better readability. Also, you're free to change the nonNull predicate to check either the whole entity, or just the id attribute (or even both). Just play a bit with it. :)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.