JEP 186: Collection Literals

Zhong Yu zhong.j.yu at
Thu Jan 23 12:53:36 PST 2014

On Thu, Jan 23, 2014 at 12:11 PM, Tom Hawtin <tom.hawtin at> wrote:
> [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.)

I on the other hand feel very uncomfortable if the same literal means
very different things in different contexts - it could be a List, a
Set, a Person, or a Dog. Inferring the meaning of the literal would
become a burden, at least for unfamiliar types - what does this mean:
`Dog dog = [blah, blah];`? Such code is not a good way to communicate
ideas between programmers.

Using words to express meanings is better than using symbols - if it
doesn't become too verbose. List.of(x,y,z) means a list of x, y, z,
simple and clear. The wordiness of Java programs makes them easier to

If we must introduce literals, I would prefer their meanings to be
context free - [x,y,z] means an immutable list, that is it.

> For maps this is more clear cut.
> import static;
> 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();

I think we should almost *never* declare a weaker type on
non-publicized variables, like
    List<Thing> things = new ArrayList<>();
instead, we should almost always declare the most specific type, like
    ArrayList<Thing> things = new ArrayList<>();
I don't want to start an argument about this issue here; it's just
that, if one adheres to the 2nd style, he'll never need
    List<Thing> things = new();
which seems ambiguous, requiring further effort in understanding;
instead, he'll only ever do
    ArrayList<Thing> things = new();
which seems very clear in its meaning.

> 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

Zhong Yu

More information about the lambda-dev mailing list