Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Handling null pointers and throwing exceptions in streams

Let's consider a Parent class which contains only one Integer attribute. I created 6 objects of parent class and with one null variable. Then I added these objects to a list.

I want to retrieve the corresponding object by the value of Integer attribute. I used Java 8 Streams for it.

Predicate<Parent> predicate = e -> e.getId() == 100; // sample attribute value
result = list.stream().filter(predicate).collect(Collectors.toList());

But I got NullPointerException, so I edited the code:

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

But I want to throw an exception if any of the object is null. If no objects in the list is null, then I want to retrieve the corresponding object from list.

How can I achieve this using a single statement using Java 8 Streams?

like image 734
Manu Joy Avatar asked Jul 10 '15 06:07

Manu Joy


People also ask

How do you handle null pointer exceptions?

In Java, the java. lang. NullPointerException is thrown when a reference variable is accessed (or de-referenced) and is not pointing to any object. This error can be resolved by using a try-catch block or an if-else condition to check if a reference variable is null before dereferencing it.

Can we throw exception in stream?

This way, you only have to write it once and call it every time you need it. To do so, you first need to write your own version of the functional interface for a function. Only this time, you need to define that the function may throw an exception.

How do you handle exception inside a stream?

Instead, you have three primary approaches: Add a try/catch block to the lambda expression. Create an extracted method, as in the unchecked example. Write a wrapper method that catches checked exceptions and rethrows them as unchecked.


1 Answers

JB Nizet answer is okay, but it uses map only for its side effects and not for the mapping operation, which is kind of weird. There is a method which can be used when you are solely interested in the side effects of something, such as throwing an exception: peek.

List<Parent> filtered = list.stream()
    .peek(Objects::requireNonNull)
    .filter(predicate)
    .collect(Collectors.toList());

And if you want your own exception just put a lambda in there:

List<Parent> filtered = list.stream()
    .peek(p -> { if (p == null) throw new MyException(); })
    .filter(predicate)
    .collect(Collectors.toList());

Checked Exceptions

If your exception is checked you can either check for null beforehand, if you don't mind traversing the list twice. This is probably best in your case, but might not always be possible.

if (list.contains(null)) throw new MyCheckedException();

You could also throw an unchecked exception in your stream pipeline, catch it and then throw the checked one:

try {
    ...
        .peek(p -> { if (p == null) throw new MyException(); })
    ...
} catch (MyException exc) {
    throw new MyCheckedException();
}

Sneaky Throw

Or you could take the elegant but controversial road and use a sneaky throw method.

But beware! This technique circumvents the checked exception system and you should know what you are doing. Be sure to declare that the surrounding method throws MyCheckedException! The compiler won't warn you if you don't, and it will likely cause weird bugs if checked exceptions appear where they are not expected.

@SuppressWarnings("unchecked")
public <T extends Throwable> void throwSneakily(Throwable t) throws T {
    throw (T) t;
}

public void m() throws MyCheckedException {
    List<Parent> filtered = list.stream()
        .peek(p -> { if (p == null) throwSneakily(new MyCheckedException()); })
        .filter(predicate)
        .collect(Collectors.toList());
}
like image 182
Lii Avatar answered Oct 24 '22 05:10

Lii