Nulls

Brian Goetz brian.goetz at oracle.com
Sat Sep 22 10:04:36 PDT 2012


> Dealing with possibly-sparse arrays in the Stream API
> proper seems to be a stretch anyway. As I always say,
> ConcurrentHashMaps and Arrays are special enough to have
> their own extended APIs that let you do non-stream-y stuff
> not directly accessible via Stream API.
> ArrayLists are a little problematic in that while most
> people treat them as dense lists, they can also be used
> as sparse (partially null) arrays. I still think that
> allowing a (Parallel)Array view of an ArrayList is likely
> the best move.
>
>> So I prefer to interpret your suggestion as "*may* ignore null
>> elements".  So in
>> this case, a reduction can ignore nulls, a find can ignore nulls, but
>> "dense"
>> ops can choose not to.

I would rather not punish everyone because some idiot puts nulls in a 
collection and that same idiot filters/maps it with lambdas that can't 
deal with nulls.

With the exception of the Option-bearing findXxx methods, we could 
declare streams to be null-oblivious, and the rest of responsibility for 
dealing with nulls goes back to the user who used a null-bearing stream 
source in the first place.

So here's a slightly less simple rule, but one which does less damage:
  - Null values are not treated specially by streams, except by findXxx 
(still to decide: throw or ignore.)  I kind of prefer throw if we're 
going to do that, since its more consistent -- it is merely enforcing an 
invariant of Optional, and then Streams has nothing to say about nulls 
at all.

We can (without undermining our copy-avoidance optimizations) add a 
filterNulls Op, by adding a stream state flag NO_NULLS and collections 
that already prohibit nulls would have that bit set.  So in this case:

   guaranteedNullFreeSource.filterNulls().map(..).toArray()

could still do the copy avoidance (and the filterNulls turns into a 
no-op.)

>> If we add a
>>
>>    T reduce(Reducer<T>, T defaultValueIfNone)
>
> Why would you add this method if you already have it? :-)
> I didn't necessarily mean that the default argument must always be last.

It was a too-subtle way of pointing out that this rule felt like we were 
extrapolating from the (currently) single data point of findXxx.


More information about the lambda-libs-spec-observers mailing list