On 07/19/2014 01:36 AM, Stuart Marks wrote:
On 7/18/14 2:17 AM, Michael Kay wrote:
On 18 Jul 2014, at 10:09, Wang Weijun <weijun.w...@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

You can combine these 2 approachesi using a Ruby like builder approach with a lambda, which provide a builder object (so static method call are replaced by instance method call) avoiding the creation of too many entry objects
Map.of(b -> b
        .entry(k0, v0)
        .entry(k1, v1)
          ...
        .entry(kN, vN))

cheers,
RĂ©mi

Reply via email to