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?
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.
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.
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.
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());
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();
}
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());
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With