JEP 186: Collection Literals

Tom Hawtin tom.hawtin at oracle.com
Thu Jan 30 17:00:49 PST 2014


On 30/01/2014 15:18, Nick Williams wrote:
> I've seen a lot of talk on mutable vs. immutable literals. I think in must cases users want their literals to generate immutable collections. However, I don't think this is an absolute rule. I also think it's an easy problem to solve. For that matter, we could also solve something that has always bothered me about Java collections: every interface is mutable. Why even LET someone call an add/update method and get a runtime exception? Wouldn't it be better to never supply an add/update method in the interface? Even better: We can implement this WITHOUT breaking binary compatibility! Observe:

For the odd case where you don't want an immutable collection, just copy 
to an implementation of you choice.

List<String> names = new ArrayList<>({"Fred", "Jim", Sheila"});

> ImmutableIterable
>     |
>     |-->ImmutableCollection
>     |       |
[...]
>     |                            |  |  |
>     |-->Iterable                 |  |  |
>             |                    |  |  |
>             |-->Collection       |  |  |

This isn't what we mean by immutable. A mutable collection is not a kind 
of an immutable collection. An immutable collection never changes under 
any circumstances ever (although it's component elements may). 
ReadOnlyCollection or simpler but unhelpful SimpleCollection, perhaps. 
(But it is immutable collections that are actually useful in method calls.)

I understand the reason the read-only separation wasn't in 1.2 was that 
there are still broken methods. Collection.contains can throw a 
ClassCastException if you get a type wrong. IIRC, various standard 
collections are mutable but not structurally modifiable, only allow 
deletion or can only be cleared. Others, such as IdentityHashMap, just 
straightforwardly break contracts. As has already been mentioned in this 
thread, some obey the interface but have exceptionally poor performance 
in normal cases (LinkedList) or corner/malicious cases (HashMap). Some 
have just peculiar constraints on their usage, such as 
Collection.synchronizedMap. And then there's things which go bump in the 
night (WeakHashMap).

So, yes there could have been a ton of types, but for better or worse 
that's not what we have.

> ImmutableList<String> list = ["hello", "world"];  //immutable
> List<String> list = ["hello", "world"];           //mutable

Legacy APIs will be using List, so the unwanted type will be used as 
arguments in method calls.

Tom



More information about the lambda-dev mailing list