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