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
m...@saxonica.com
+44 (0118) 946 5893



On 17 Jul 2014, at 01:46, Stuart Marks <stuart.ma...@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


Reply via email to