At the risk of a can of worms, or at least of raising something that has
long since been discussed and rejected...

This discussion of unmodifiable lists brings me back to the thought that
there would be good client-side reasons for inserting an UnmodifiableList
interface as a parent of LIst, not least because all our unmodifiable
variants from the Collections.unmodifiableList proxy onward fail the Liskov
substitution test for actually "being contract-fulfilling Lists".

Is this something that has been considered and rejected? (If so, is it easy
to point me at the discussion, as I expect I'd find it fascinating). Is it
worth considering, might it have some merit, or merely horrible
unforeseen-by-me consequences to the implementation?

Cheers,
Simon



On Thu, Nov 5, 2020 at 10:30 AM Stuart Marks <sma...@openjdk.java.net>
wrote:

> On Wed, 4 Nov 2020 23:03:02 GMT, Paŭlo Ebermann <github.com+
> 645859+ep...@openjdk.org> 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?
>
> It's an implementation invariant that the internal array be Object[].
> Having it be something other than Object[] can lead to subtle bugs. See
> [JDK-6260652](https://bugs.openjdk.java.net/browse/JDK-6260652) for
> example.
>
> -------------
>
> PR: https://git.openjdk.java.net/jdk/pull/1026
>


-- 
Simon Roberts
(303) 249 3613

Reply via email to