JEP 186: Collection Literals

Tom Hawtin tom.hawtin at oracle.com
Thu Jan 23 10:11:58 PST 2014


[These are my own opinions.]

Pure library vs language+library implementation. I think there's two 
aspects here.

Current bytecode for varargs is quite verbose, and the JVM has issues 
with long bytecode. Though this could be treated as an orthogonal issue 
or ignored.

The other aspect is syntax.

import static java.util.Lists.list;
     List<Thing> things = list(x, y, z);

vs

     List<Thing> things = [x, y, z]

I think the latter is significantly cleaner and removes duplication. 
(Type of collection literal is based on the target type.)

For maps this is more clear cut.

import static java.util.Maps.map;
import static java.util.Maps.entry;
     Map<Key,Value> things = map(entry(k, v), entry(l, w), entry(m, x));

vs

     Map<Key,Value> things = [[k, v], [l, w], [m, x]]

This works out due to the benefits of static [target] typing.

Assuming general, the syntax above would need some kind of language 
addition to the type. (A static field is not enough.) Perhaps something 
based on constructor syntax:

public interface List<T> ... {
     List[T... values] {
         return
             values.length==0 ? Collections.emptyList() :
             values.length==1 ? new SingletonImmutableList<>(value[0]) :
                                new ImmutableList<>(values);
     }

Whilst we are in this area, we still have a lot of redundancy 
constructing objects where the type is 90% obvious. As in:

     List<Thing> things = new ArrayList<>();

should be:

     List<Thing> things = new();

or

     List<Thing> things = {};


Moving on. There are broadly two security/robustness problems that come 
up with collections and arrays.

Firstly, when a collection is passed between objects it requires an 
explicit copy as the receiver cannot trust that it wont be subsequently 
mutated or has a non-default implementation. java.util collection types 
are bad when they leak into parameters. Immutability makes collections 
safe-by-default for this aspect.

Secondly, collections and arrays may behave badly with respect to 
equality (including hashCode and compareTo). Unfortunately there is 
tradition of not making equals and hashCode final for reference types 
(particularly in interfaces). As the like of List.indexOf mandate use of 
equals we need to switch to non-complying implementations 
(IdentityArrayList) to keep safe. It may therefore, make sense to be 
able to select default implementation type on type of "generic argument".

     Set<String> strs = [ "str" ]; // an ImmutableHastSet
     Set<JWindow> windows = [ window ]; // an IdentityImmutableHashSet

Also applies to Comparable, so may have ImmutableTreeHashSet<String> 
(guaranteed O(log n) worst-case sustained performance).

Subclassable or otherwise mutable value types are a basket case. Nothing 
can be done for them, other than an assisted @Deprecated.

Tom


More information about the lambda-dev mailing list