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

Reply via email to