Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make java 8 Stream map continuously with null check

I have this piece of code

Coverage mainCoverage = illus.getLifes().stream()
    .filter(Life::isIsmain)
    .findFirst()
    .orElseThrow(() -> new ServiceInvalidAgurmentGeneraliException(env.getProperty("MSG_002")))
    .getCoverages()  
    .stream() // <==may cause null here if list coverage is null
    .filter(Coverage::isMainplan)
    .findFirst()
    .orElseThrow(() -> new ServiceInvalidAgurmentGeneraliException(env.getProperty("MSG_002")));

which is totally work fine but I think It's a little bit messy and not cover all the null pointer exception possible (see the comment).

I try to refactor this code into

Coverage mainCoverage1 = illus.getLifes().stream()
    .filter(Life::isIsmain)
    .map(Life::getCoverages)
    .filter(Coverage::isMainplan) //<== cannot filter from list coverage to one main coverage
    ...

Seem after I map the life to coverage it is not a list of coverage anymore. So the question is how I can refactor the first section into null safe and maybe shorten it?

like image 301
Dang Nguyen Avatar asked Dec 25 '18 01:12

Dang Nguyen


People also ask

How do you null in checkin stream?

We can use lambda expression str -> str!= null inside stream filter() to filter out null values from a stream.

How do I stop null pointer exception in Java 8 streams?

Java 8 introduced an Optional class which is a nicer way to avoid NullPointerExceptions. You can use Optional to encapsulate the potential null values and pass or return it safely without worrying about the exception. Without Optional, when a method signature has return type of certain object.

How do you handle a null map in Java?

You must try and ensure that your Map doesn't allow null writes such as element2. put("e",null); in reality. This was corrected in JDK itself with Map. of implementation in Java-9 as well.

How to filter null values from stream of mappings in Java?

Using Java 8 We know that Stream.filter () returns a stream consisting of the elements that match the given predicate. We can use a lambda expression to filter null values from the stream of mappings, as shown below: 3. Handle null map All the above codes will throw a NullPointerException if the map is null.

How to use map function in Java 8 stream API?

As I said, Map function in Java 8 stream API is used to transform each element of Collection be it, List, Set, or Map. In this Java 8 tutorial, we have used map function for two examples, first to convert each element of List to upper case, and second to square each integer in the List.

How to create a null-safe collection from a stream in Java?

Using Optional can be arguably considered as the best overall strategy to create a null-safe collection from a stream. Let's see how we can use it followed by a quick discussion below: Optional.ofNullable (collection) creates an Optional object from the passed-in collection. An empty Optional object is created if the collection is null.

What is stream in Java 8?

Java 8 stream is widely used feature to write code in functional programming way. In this tutorial, we’ll discuss how to use Streams for Map creation, iteration and sorting.


1 Answers

Life::getCoverages returns a collection hence the filter Coverage::isMainplan will not work, instead you should flatMap the sequences returned after .map(Life::getCoverages) then apply the filter operation on the Coverage:

Coverage mainCoverage = 
          illus.getLifes()
               .stream()
               .filter(Life::isIsmain)               
               .map(Life::getCoverages)
               //.filter(Objects::nonNull) uncomment if there can be null lists
               .flatMap(Collection::stream) // <--- collapse the nested sequences
               //.filter(Objects::nonNull) // uncomment if there can be null Coverage
               .filter(Coverage::isMainplan)
               .findFirst().orElse(...);

I've added a few things to your code:

  1. I've added .filter(Objects::nonNull) after .map(Life::getCoverages) which you can uncomment given the elements returned could potentially be null.
  2. I've added .flatMap(Collection::stream) which returns a stream consisting of the results of replacing each element of this stream with the contents of a mapped stream produced by applying the provided mapping function to each element.
  3. I've added another .filter(Objects::nonNull) which you can uncomment given the elements returned after flatMap could potentially be null.
  4. We're then at a stage in which we can apply .filter(Coverage::isMainplan) and finally, retrieve the first object meeting the criteria via findFirst and if none then provide a default value via orElse.

I'd suggest having a look at the following blogs to get familiar with the flatMap method:

  • Java 8 flatMap example
  • Understanding flatMap
  • A Guide to Streams in Java 8: In-Depth Tutorial with Examples
like image 179
Ousmane D. Avatar answered Nov 15 '22 17:11

Ousmane D.