JEP 186: Collection Literals

Nick Williams nicholas+openjdk at nicholaswilliams.net
Thu Jan 30 07:18:19 PST 2014


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:

ImmutableIterator
Iterator

ImmutableIterable
   |
   |-->ImmutableCollection
   |       |
   |       |-->ImmutableList----------|
   |       |                          |
   |       |-->ImmutableSet--------|  |
   |       |                       |  |
   |       |-->ImmutableQueue---|  |  |
   |                            |  |  |
   |-->Iterable                 |  |  |
           |                    |  |  |
           |-->Collection       |  |  |
                   |            |  |  |
                   |-->List<----)--)--|
                   |            |  |
                   |-->Set<-----)--|
                   |            |
                   |-->Queue<---|

ImmutableMap
   |
   |-->Map

Then you just need to move all the mutating methods of each interface into its immutable superinterface. Voila! It doesn't break any existing code, but you can now use immutable collections:

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

ImmutableMap<String, String> map = { "hello":"world", "foo":"bar" };  //immutable
Map<String, String> map = { "hello":"world", "foo":"bar" };           //mutable

Nick

On Jan 23, 2014, at 6:58 PM, Remi Forax wrote:

> On 01/23/2014 09:53 PM, Zhong Yu wrote:
>> 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;
> 
> I agree.
> 
> The main issue is with a code like this
>   List<Thing> things = new ArrayList<>();
>   for(int i=0; i< things.size(); i++) {
>     ...   // i is used here
>   }
> 
> because it can be changed to the code below without any warnings
>   List<Thing> things = new LinkedList<>();
>   for(int i=0; i< things.size(); i++) {
>     ...  // i is used here
>   }
> 
> The complexity of the first code is O(n) the second one is O(n2).
> 
> cheers,
> Rémi
> 
> 



More information about the lambda-dev mailing list