As will surprise no one, this was extensively discussed during the development of the Streams API.  (Our default position on "convenience methods" is hostile.  While everyone sees the benefit of convenience methods (it's convenient!), most people don't see the cost, which includes the complexity for users to understand the model by looking at the API; having lots of ad-hoc convenience method obscures the underlying model, making it harder for everyone to learn or reason about.  That default position seems to stand up pretty well here, as the stream API is pretty well factored.)

Let's be honest: the "convenience" or concision of being able to say .toList() instead of .collect(toList()) is really small.  I don't think you'll be able to justify it by saying "but we do it a lot."  (Digression: to whoever is about to say "then why `toArray()`?  Arrays are different; for better or worse, they're part of the language, and they lend themselves particularly poorly to the Collector API, and there are particular parallelization optimizations that are possible for arrays that can't be accessed through Collector.  End digression.)

It is possible, however, that one could justify `toList()` on the basis of _discoverability_.  (Though I'm having a hard time seeing any world where `toSet()` makes the cut.)  New users who approach streams will not easily be able to figure out how to materialize a list from a stream, even though this is an entirely reasonable and quite common thing to want to do.  Having to learn about `collect()` first is asking a lot of users who are still wrapping their heads around streams.  Not only would `toList()` be more discoverable, it would provide a path to discovery of the rest of the `collect()` API.  This is a point in its favor.

A significant downside of adding `toList()` is that by diluting the orthogonality of the existing API, it provides both incentive and justification for further dilution, leading to someplace we don't want to be.  (And, the cost of that falls heavily on the stewards, which in turn takes time away from far more valuable activities.)

Put it this way: imagine we have a budget of one convenience method in Stream for every five years.  Is this the one we want to spend the next five year's budget on?  (And, who of the proponents will volunteer to answer the next 200 "I have an idea for a stream method" mails, explaining that the budget is spent?)


So, summary:

 - I won't outright veto `toList`, as I would for almost all other "convenience" streams additions, because this one actually has a valid non-convenience argument;
 - But, it's still not a slam dunk.


On 12/9/2018 5:44 PM, Rob Griffin (rgriffin) wrote:
Hi,

I have raised an enhancement request (Incident Report 913453) about adding some 
convenience methods to the Stream interface that collect the stream and Pallavi 
Sonal asked me to start a thread here about that.

More than 50% of our Stream collect calls use Collectors.toList() or 
Collectors.toSet() as arguments so I think it would be very handy if the Stream 
interface had default collectToList and collectToList and collectToMap methods.

The advantages are:
        it would be easier to use code completion in IDEs. There are lot of 
classes starting with Collect so finding the Collectors class is a bit of a 
pain.
        one less method call in what is usually a long chain of calls.

Regards,

Rob Griffin
Software Analyst, Spotlight on SQL Server
Quest | R&D
rob.grif...@quest.com


Reply via email to