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?
We can use lambda expression str -> str!= null inside stream filter() to filter out null values from a stream.
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.
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.
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.
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.
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.
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.
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:
.filter(Objects::nonNull)
after .map(Life::getCoverages)
which you can uncomment given the elements returned could potentially be null..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. .filter(Objects::nonNull)
which you can uncomment given the elements returned after flatMap
could potentially be null..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:
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