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