Re: RFR: 8180352: Add Stream.toList() method

2020-11-04 Thread Paŭlo Ebermann
On Wed, 4 Nov 2020 08:53:23 GMT, Zheka Kozlov 
 wrote:

>> 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.
>> 
>> In the past we've kept most things from the Collections Framework as 
>> implementations of Collector, not directly on Stream, whereas only 
>> fundamental things (like toArray) appear directly on Stream. This is true of 
>> most Collections, but it does seem that List is special. It can be a thin 
>> wrapper around an array; it can handle generics better than arrays; and 
>> unlike an array, it can be made unmodifiable (shallowly immutable); and it 
>> can be value-based. See John Rose's comments in the bug report:
>> 
>> https://bugs.openjdk.java.net/browse/JDK-8180352?focusedCommentId=14133065&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-14133065
>> 
>> This operation is null-tolerant, which matches the rest of Streams. This 
>> isn't specified, though; a general statement about null handling in Streams 
>> is probably warranted at some point.
>> 
>> Finally, this method is indeed quite convenient (if the caller can deal with 
>> what this operation returns), as collecting into a List is the most common 
>> stream terminal operation.
>
> Changes requested by orio...@github.com (no known OpenJDK username).

Looking at the linked issue, I see [this comment from Rémi 
Forax](https://bugs.openjdk.java.net/browse/JDK-8180352?focusedCommentId=14171626&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-14171626):

> Please talk with Brian about this change because it nulls a property of the 
> Stream API we (the lambda-util group) have take time to keep.
The whole Stream API doesn't depends on the Collection API, [...] so the Stream 
API can be easily integrated with other collection API if in the future we want 
by example add a persistent collection API with no link with java.util.List.

That's an argument I can understand – as is, the Stream API works just as well 
with collections from e.g. Scala's or Kotlin's (or Ceylon's) collection 
libraries instead of the java.util ones, just using different collectors. 
Adding a method which directly returns a java.util.List somewhat couples it to 
the Java Collection API.

Now this was mentioned two and a half year ago. Did something change which made 
this consideration irrelevant? I would expect at least some mention of it in 
the discussion here.

-

PR: https://git.openjdk.java.net/jdk/pull/1026


Re: RFR: 8180352: Add Stream.toList() method

2020-11-04 Thread Paŭlo Ebermann
On Tue, 3 Nov 2020 01:33:32 GMT, Stuart Marks  wrote:

> 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.
> 
> In the past we've kept most things from the Collections Framework as 
> implementations of Collector, not directly on Stream, whereas only 
> fundamental things (like toArray) appear directly on Stream. This is true of 
> most Collections, but it does seem that List is special. It can be a thin 
> wrapper around an array; it can handle generics better than arrays; and 
> unlike an array, it can be made unmodifiable (shallowly immutable); and it 
> can be value-based. See John Rose's comments in the bug report:
> 
> https://bugs.openjdk.java.net/browse/JDK-8180352?focusedCommentId=14133065&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-14133065
> 
> This operation is null-tolerant, which matches the rest of Streams. This 
> isn't specified, though; a general statement about null handling in Streams 
> is probably warranted at some point.
> 
> Finally, this method is indeed quite convenient (if the caller can deal with 
> what this operation returns), as collecting into a List is the most common 
> stream terminal operation.

src/java.base/share/classes/java/util/ImmutableCollections.java line 199:

> 197:  * safely reused as the List's internal storage, avoiding a 
> defensive copy. Declared
> 198:  * with Object... instead of E... as the parameter type so that 
> varargs calls don't
> 199:  * accidentally create an array of type other than Object[].

Why would that be a problem? If the resulting list is immutable, then the 
actual array type doesn't really matter, right?

-

PR: https://git.openjdk.java.net/jdk/pull/1026