RFR: 8180352: Add Stream.toList() method

Brian Goetz brian.goetz at oracle.com
Tue Nov 3 18:02:37 UTC 2020


>> This change introduces a new terminal operation on Stream. This looks like a
>> convenience method for Stream.collect(Collectors.toList()) or
>> Stream.collect(Collectors.toUnmodifiableList()), but it's not. Having this
>> method directly on Stream enables it to do what can't easily by done by a
>> Collector. In particular, it allows the stream to deposit results directly into
>> a destination array (even in parallel) and have this array be wrapped in an
>> unmodifiable List without copying.
>>
>> Hi Stuart,
>> I'm Okay with the idea of having a method toList() on Stream but really dislike the proposed semantics because tit is neither stream.collect(toList()) nor stream.collect(toUnmodifiableList()) but something in between.
>>
>> It's true that a Stream support nulls, we want people to be able map() with a method that returns null and then filter out the nulls (even if using flatMap for this case is usually a better idea),
>> but it doesn't mean that all methods of the Stream interface has to support nulls, the original idea was more to allow nulls to flow in the stream because at some point they will be removed before being stored in a collection.

Uhm ... no and no.

It does mean that all methods of the stream interface have to support 
nulls.  Streams are null tolerant.  Because ...

The original idea was not "the nulls can be removed later."  The 
original idea was "Streams are plumbing, they pass values through 
pipelines, to user-specified lambdas, into arrays, etc, and the stream 
plumbing should not have an opinion on the values that are flowing 
through."   And this was the right choice.

There is no value in making users remember which stream methods are 
null-hostile and which are null-tolerant; this is just more accidental 
complexity.  And the root cause of that accidental complexity is the 
misguided belief that we can (and should) contain the consequences of 
nullity by making ad-hoc restrictions about nullity.   That doesn't 
work, and all it does is add more complexity and more ways for X to not 
interact with Y.

I understand the hatred for nulls, but it's a fantasy to think we can 
contain them with ad-hoc restrictions.   And the aggregate cost in 
complexity of all the ad-hoc decisions is pretty significant. Stuart 
made the right choice here.




More information about the core-libs-dev mailing list