RFR: 8180352: Add Stream.toList() method
forax at univ-mlv.fr
forax at univ-mlv.fr
Tue Nov 3 19:24:36 UTC 2020
----- Mail original -----
> De: "Brian Goetz" <brian.goetz at oracle.com>
> À: "Remi Forax" <forax at univ-mlv.fr>, "Stuart Marks" <smarks at openjdk.java.net>
> Cc: "core-libs-dev" <core-libs-dev at openjdk.java.net>
> Envoyé: Mardi 3 Novembre 2020 19:02:37
> Objet: Re: RFR: 8180352: Add Stream.toList() method
>>> 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.
A stream is computation, so i agree that letting nulls to flow is the right call.
So i stand corrected on that point.
>
> 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.
I think that ship has sailed a long ago.
Some collectors are null hostile, some are not.
You can make a point that a Collector is technically not the Stream API per se.
[...]
Let's take a step back,
if we introduce a method toList() on Stream it will be used a lot, i mean really a lot, to the point where people will change the code from stream.collect(Collectors.toList()) to use stream.toList() instead.
Because of that, i don't think we even have the choice of the semantics for Stream.toList(), it has to be the same as stream.collect(Collectors.toList()).
So you are right that toList() can not be null hostile because Collectors.toList() is not null hostile.
But it can not be immutable too, for the same reason.
> Stuart made the right choice here.
I would say half of the right choices, null hostile: right, immutable: wrong :)
And if we at some point introduce a method toImmutableList() on Stream, it will have to be null hostile.
Rémi
More information about the core-libs-dev
mailing list