please review draft JEP: Convenience Factory Methods for Collections

Stuart Marks stuart.marks at oracle.com
Fri Jul 18 23:36:35 UTC 2014


On 7/18/14 2:17 AM, Michael Kay wrote:
> On 18 Jul 2014, at 10:09, Wang Weijun <weijun.wang at oracle.com> wrote:
>> A .with(k, v) to create a new immutable map with an extra pair.
>
> Yes, that's the same as my A.add(k,v) -> A proposal.
>
> Works whether A is mutable or immutable.

I don't think we want to have a Map.add(k,v) instance method (or default method) 
for immutable maps or for constructing them.

For a fast, compact, immutable map implementation, the only way to implement 
Map.add() would be to copy the entire contents plus the additional pair into a 
new map. For creating maps with small numbers of entries, this isn't really a 
big deal, but if you have something like

     Map.of()
        .add(k0, v0)
        .add(k1, v1)
          ...
        .add(kN, vN);

this would result in O(N^2) performance and space allocation, though most of the 
allocated space is garbage.

Of course, one could avoid the copying overhead by making the immutable maps 
persistent (i.e., sharing their unmodified portions) but that is an entirely 
different discussion.

I kind of think you're after the ability to chain the method calls. This is 
certainly convenient and has no arbitrary restrictions on the number of 
elements. To do something like this we'd put the chainable methods on a builder 
instead:

     Map.builder()
        .add(k0, v0)
        .add(k1, v1)
          ...
        .add(kN, vN)
        .build();

This is somewhat more cluttered than the Map.of(Entry...) approach:

     Map.of(
         entry(k0, v0),
         entry(k1, v1),
           ...
         entry(kN, vN));

but it might make up for it with flexibility. I hesitate a bit to pursue the 
builder approach, because it can easily get bogged down with additional 
features, but the special considerations for Map might require it.

s'marks



More information about the core-libs-dev mailing list