please review draft JEP: Convenience Factory Methods for Collections
Remi Forax
forax at univ-mlv.fr
Sat Jul 19 09:04:27 UTC 2014
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.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
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
More information about the core-libs-dev
mailing list