please review draft JEP: Convenience Factory Methods for Collections
Stuart Marks
stuart.marks at oracle.com
Thu Jul 17 21:36:50 UTC 2014
On 7/17/14 12:21 AM, Michael Kay wrote:
> Set.of() and List.of() look very attractive; Map.of() looks very ugly.
The proposed Map.of() API offends our sensibilities as programmers, because of
its repetition and its lack of generality. I think that's what you mean by
"ugly". There is a indeed certain amount of unpleasantness in the specification
and implementation of the fix-arg Map.of() methods.
But this doesn't show up in actual usage.
> I would much prefer to write something like
>
> Map.of(
> Map.pair(key, value),
> Map.pair(key, value),
> Map.pair(key, value)
> );
>
> and have no limit on the number of pairs. (Don't care how it works internally...)
OK, let's posit the existance of a static Map.entry(k,v) method which will
return an AbstractMap.SimpleImmutableEntry of (k,v). (AM.SIE would make a nice
pair class but its name is so damned long!) Users will presumably statically
import this method. One could then write:
Map<String,Integer> map = Map.of(
entry("BMW", 5),
entry("Mercedes", 3),
entry("Audi", 4),
entry("Ford", 10));
Compare this to the old-fashioned create-then-add technique:
Map<String,Integer> map = new HashMap<>();
map.put("BMW", 5);
map.put("Mercedes", 3);
map.put("Audi", 4);
map.put("Ford", 10);
map = Collections.unmodifiableMap(map);
Compared to this, the varargs list of entries reduces the visual clutter some,
but not a tremendous amount. There is a smaller difference if you don't care to
create the unmodifiable wrapper in the second case.
Now compare this to the proposed fixed-args version:
Map<String,Integer> map = Map.of(
"BMW", 5,
"Mercedes", 3,
"Audi", 4,
"Ford", 10);
That looks quite a bit simpler. In particular, there is no longer a pair of
parentheses around each key-value pair like there is in the other example. That
makes things visually much nicer in my estimation.
The varargs of map entries is clearly more general. Do we need that generality,
and are we willing to put up with more clutter to get that generality?
> The last thing I want is to have to rewrite all my code when someone asks me to add a sixth entry to the map initialization!
Well, Remi had proposed raising the limit. Suppose we offered 7 key-value pairs
instead of 5. Would you then complain about having to rewrite your code if you
had to add an 8th entry to the map? (Repeat for any N, N+1.) A fixed-arg
approach, while not fully general, can be tailored to solve 80%, or 95%, or
99.9%, or whatever percentage of the cases we choose to solve. Beyond a certain
point the benefit provided by a varargs approach vs a fixed N approach becomes
vanishingly small. I don't have the numbers at my fingertips, that point is
reached very quickly, say around N = 5. But maybe it's a bit higher.
The tradeoff here is that we are willing to put up with a certain amount of API
ugliness in order to make people's programs nicer. If we can cover a vast
majority of people's cases, that's just fine, even if it's not fully general.
s'marks
(Example data from examples.javacodegeeks.com)
> Michael Kay
> Saxonica
> mike at saxonica.com
> +44 (0118) 946 5893
>
>
>
> On 17 Jul 2014, at 01:46, Stuart Marks <stuart.marks at oracle.com> wrote:
>
>> Hi all,
>>
>> Please review this draft JEP for Convenience Factory Methods for Collections:
>>
>> https://bugs.openjdk.java.net/browse/JDK-8048330
>>
>> Brief background: several times over the years there have been proposals to add "collection literals" to the language. The most recent round of this was in regard to JEP 186, a research JEP to explore this topic. That effort was concluded by Brian Goetz, as summarized in this email:
>>
>> http://mail.openjdk.java.net/pipermail/lambda-dev/2014-March/011938.html
>>
>> Essentially, the idea of adding collection literals to the language was set aside in favor of adding some library APIs, not entirely unlike collection literals, that make it more convenient to create collections. That's what this proposal is.
>>
>> Share and enjoy,
>>
>> s'marks
>>
>
More information about the core-libs-dev
mailing list