Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Correct lambda filter implementation

I have a case where I need to

  • map an object, if the mapping function throws an exception, I map it to null.
  • filter the mapped stream for null object, if null then throw Exception, else collect to List.

How would I achieve this?

list.stream().map(ob-> {
    try {
        // cannot throw only catch 
        return function(ob);
    } catch (Exception e) {
        log.error(e);
        return null;
    }            
}).filter(Objects::isNull).findFirst().orElseThrow(Exception::new);

Now my question is how should I tweak/refactor the above lambda to throw new Exception() on null or else collect(Collectors.toList()).

like image 477
Dota2 Avatar asked Jun 07 '26 03:06

Dota2


1 Answers

If you intend to report the exception (which is a good idea), you should never map it to null in the first place. Since certain functional interfaces do not allow to throw a checked exception, you should rethrow it wrapped in an unchecked exception:

try {
    List<Object> result = list.stream().map(ob-> {
        try {
            // cannot throw checked exception types
            return function(ob);
        } catch(Exception e) {
            throw new CompletionException(e);
        }
    }).collect(Collectors.toList());
} catch(CompletionException ex) {
    throw (Exception)ex.getCause();
}

The key point is that this will throw the original exception, with all information contained within it, instead of creating a new instance via new Exception() that would contain no information about the cause at all.

Note that for some cases, there are already dedicated exception types, e.g. UncheckedIOException to wrap an IOException. In other cases, it might be cleaner to declare your own unchecked exception type, to be sure that it doesn’t get mixed up with other exceptions thrown by other components of your application.

like image 88
Holger Avatar answered Jun 08 '26 16:06

Holger



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!