RFR(m): JEP 269 initial API and skeleton implementation (JDK-8139232)
Stuart Marks
stuart.marks at oracle.com
Wed Nov 25 02:53:04 UTC 2015
On 11/24/15 8:55 AM, Peter Levart wrote:
> Hi Stuart,
>
> Since those factory methods construct general purpose immutable collections, I
> miss methods that act as copy constructors (general purpose collection
> implementations should have them, says recommendation):
>
>
> public static <E> List<E> copyOf(Collection<? extends E> collection);
>
> public static <E> Set<E> copyOf(Collection<? extends E> collection);
>
> public static <K, V> Map<K, V> copyOf(Map<? extends K, ? extends V> map);
>
>
> Sometimes it would be useful also to trust the copy to contain elements of the
> specified type (since those are immutable collections, Class arguments are
> needed only at construction time to do the check while constructing):
>
>
> public static <E> List<E> copyOf(Collection<? extends E> collection, Class<E>
> elementType);
>
> public static <E> Set<E> copyOf(Collection<? extends E> collection, Class<E>
> elementType);
>
> public static <K, V> Map<K, V> copyOf(Map<? extends K, ? extends V> map,
> Class<K> keyType, Class<V> valueType);
>
>
> As an optimization, those copyOf methods could be specified to return the
> passed-in collection if it was already of the correct "immutable" type:
>
> List<String> strings = List.of("a", "b", "c");
> assert List.copyOf(strings) == strings;
> assert List.copyOf(strings, String.class) == strings; // just checks the elements
>
>
> This is different from Collections.immutableXXX(xxx) since the later can not be
> used to make "defensive" copies. For example:
>
>
> class SomeBean {
> Set<Option> options = Set.of();
>
> Set<Option> getOptions() {
> return options;
> }
>
> void setOptions(Set<Option> options) {
> this.options = Set.copyOf(options, Option.class);
> }
> }
>
>
> Or would that be beyond the scope of this JEP?
I hesitate to declare it out of scope, inasmuch as we've considered similar
things as part of this proposal in the past (in earlier JEP drafts). But these
discussions have tended to lead away from the original goal of providing a
"collection literals"-like mechanism in the library. In order to get something
in that's simple, small, and useful, we've left things like this out of the
proposal for now.
I mean, you raise a bunch of interesting issues, and it's quite tempting for me
to dive right in and start discussing them! But what I need to do now is focus
on getting the API approved and checked in, and then work on bringing up the
optimized implementations to replace the skeleton implementations that are in
the current webrev.
With the current proposal it's at least possible to do something like what you
want by streaming into an array that's then passed to one of the
array/varargs-consuming methods. This isn't as convenient as a "copy
constructor" style factory method, but it's a whole lot more flexible. You can
reject runtime type mismatches, or just filter them out, or filter out duplicate
set elements, etc.
So, I'd like to postpone discussion of this area for now. There might be time in
JDK 9 to pursue this, but it depends on the schedule, and how long it takes to
implement and tune the optimized implementations.
Thanks for your understanding.
s'marks
More information about the core-libs-dev
mailing list