How should we control jdk8 flow for null values

Hi, Java developers,

I know this question may be a bit in advance , since the JDK8 has not yet been released (and not now). But I read some articles about lambda expressions and especially about the part associated with the new collection API known as stream.

Here is an example in a Java Magazine article (this is an otter population algorithm ..):

 Set<Otter> otters = getOtters(); System.out.println(otters.stream() .filter(o -> !o.isWild()) .map(o -> o.getKeeper()) .filter(k -> k.isFemale()) .into(new ArrayList<>()) .size()); 

My question is, what happens if in the middle of the inner iteration of Set one of the otters is null?

I would expect a NullPointerException to be thrown, but maybe I still adhere to the previous development paradigm (non-functional), can someone enlighten me how this should be handled?

If this does raise a NullPointerException, I consider this function to be quite dangerous and will only need to be used as shown below:

  • Developer to ensure that there is no null value (possibly using the previous .filter (o β†’ o! = Null))
  • Developer to ensure that the application never generating a null otter or a special NullOtter object for processing.

What is the best option or any other option?

Thank!

+48
java null java-8 java-stream
Jun 13 '13 at 7:00
source share
5 answers

Modern thinking, it seems, should β€œtolerate” zeros, that is, resolve them at all, although some operations are less tolerant and may ultimately throw NPE. See the discussion of zeros on the Lambda Libraries expert group mailing list, specifically this post . After that, there was consensus around option No. 3 (with a notable objection from Doug Lee). So yes, the OP's concern regarding pipelines exploding with NPE is, indeed.

It’s not for nothing that Tony Hoar mentioned the zeros as β€œA billion dollar error.” Working with zeros is a real pain. Even with classic collections (excluding lambda or threads) zeros are problematic. Like the fge mentioned in the comment, some collections are null while others are not. With nullable collections, this introduces ambiguity into the API. For example, with Map.get (), a null return indicates either that the key is present and its value is null, or that the key is not in place. Additional work needs to be done to eliminate these cases.

The usual use for null is to indicate the absence of a value. The approach to consider this proposal for Java SE 8 is to introduce a new type java.util.Optional that encapsulates the presence / absence of a value, along with the behavior of providing a default value or throwing an exception or calling a function, etc. if value is missing. Optional used only by the new APIs, but everything else on the system must still put up with the possibility of zeros.

My advice is to avoid actual null references as much as possible. It is difficult to see from the given example how there can be a "zero" otter. But if necessary, OP's suggestions on filtering zero values ​​or matching them with a sentinel object (

+28
Jun 14 '13 at 18:59
source share
β€” -

Stuart's answer provides a great explanation, but I would like to give another example.

I ran into this problem when trying to execute reduce on a stream containing null values ​​(actually it was LongStream.average() , which is a type of reduction). Since average () returns an OptionalDouble , I assumed that Stream might contain zeros, but a NullPointerException was thrown instead. This is due to Stuart's explanation of null v. Empty

So, as the OP suggests, I added a filter as follows:

 list.stream() .filter(o -> o != null) .reduce(..); 

Or as the tangents listed below, use the predicate provided by the Java API:

 list.stream() .filter(Objects::nonNull) .reduce(..); 

From a discussion on the Stuart mailing list, related: Brian Goetz on zeros in threads

+41
Jun 21 '14 at 15:26
source share

Although the answers are 100% correct, a small suggestion is to handle the case of the list itself with Optional :

  List<String> listOfStuffFiltered = Optional.ofNullable(listOfStuff) .orElseGet(Collections::emptyList) .stream() .filter(Objects::nonNull) .collect(Collectors.toList()); 

The Optional.ofNullable(listOfStuff).orElseGet(Collections::emptyList) will allow you to understand well when listOfStuff is null and returns an empty list instead of a failure with a NullPointerException.

+19
Aug 29 '16 at
source share

If you just want to filter the null values ​​from the stream, you can simply use the java.util.Objects.nonNull (Object) method reference. From the documentation:

This method exists for use as a Predicate , filter(Objects::nonNull)

For example:

 List<String> list = Arrays.asList( null, "Foo", null, "Bar", null, null); list.stream() .filter( Objects::nonNull ) // <-- Filter out null values .forEach( System.out::println ); 

This will print:

 Foo Bar 
+12
Mar 04 '16 at 19:48
source share

An example of how to avoid null, for example. use filter before grouping By

Filter out null instances before grouping By.

Here is an example
 MyObjectlist.stream() .filter(p -> p.getSomeInstance() != null) .collect(Collectors.groupingBy(MyObject::getSomeInstance)); 
+4
Aug 25 '15 at 15:23
source share



All Articles