JEP 186: Collection Literals
David M. Lloyd
david.lloyd at redhat.com
Thu Jan 30 07:40:08 PST 2014
I think the big hangup is that we (still) don't think of types as
"general" versus "specific" - I think most people think of the
inheritance relationship as "is-a".
Using this way of thinking, by your diagram, a List "is-a"
ImmutableList. But... it's mutable! *brain explode*
Now I'm not a proponent of this way of thinking - I think it's outdated
and frankly just wrong - but I'm sure this is a prime reason why this
kind of thing wasn't adopted long ago (you're definitely not the first
person to suggest such a thing, that's for sure).
Another reason that has (I believe) been frequently cited is that this
causes a sort of explosion of collection types. Though I don't find
this reason as compelling in this era of XX- and XXX-gigabyte RAM systems.
On 01/30/2014 09:18 AM, 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:
>
> 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
>>
>>
>
>
--
- DML
More information about the lambda-dev
mailing list