chen870647924 / guava-libraries

Automatically exported from code.google.com/p/guava-libraries
Apache License 2.0
0 stars 0 forks source link

A way to avoid redundant type parameters for ImmutableMap.builder() #883

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
When building immutalbe maps/lists you allways have the problem, that you will 
have respecify the element type, with the builder method.

So you end up writing things like:

public static final ImmutableMap<String, String> STRINGS = 
    ImmutableMap.<String, String> builder()
        .put("A", "Foo")
        .put("B", "Foo")
        .put("C", "Foo")
        .build();

If you had a "builder" method, that takes the first value(-pair) you could 
write:

public static final ImmutableMap<String, String> STRINGS = 
    ImmutableMap
        .builder("A", "Foo")
        .put("B", "Foo")
        .put("C", "Foo")
        .build();

It also could be named "put" instead.

Original issue reported on code.google.com by drothma...@googlemail.com on 25 Jan 2012 at 3:13

GoogleCodeExporter commented 9 years ago
If you wanted this to look the same, then you could use similar idea to 
CacheBuilder where the parameter types are fixed when build()ing or when adding 
a removalListener, rather than when creating the builder. Something like 
ImmutableMapGenericBuilder returned from the first put?

Original comment by joe.j.kearney on 26 Jan 2012 at 9:05

GoogleCodeExporter commented 9 years ago
Well, the CacheBuilder approach would be another option, but this would require 
a more major refactoring of the Immutable***.Builder classes. So I think a 
simple factory method with prototype-values, would be more light weight and 
more intuitive.
Also it is really simple to implement:

public static <K, V> ImmutableMap.Builder<K, V> builder(final K k, final V v) {
    return ImmutableMap.<K, V> builder().put(k, v);
}

that's all...

Original comment by drothma...@googlemail.com on 27 Jan 2012 at 8:41

GoogleCodeExporter commented 9 years ago
I simply use ImmutableMap.of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K 
k5, V v5) and its overloads when I need less than 5 mappings. In the rare cases 
where I need more than 5 mappings, I use the Builder, accepting that I have to 
respecify the generics on the Builder.

I think that an overload accepting prototype values would complicate the API, 
for a small benefit, in the rare case where you need more than 5 mappings.

Original comment by nev...@gmail.com on 27 Jan 2012 at 4:20

GoogleCodeExporter commented 9 years ago
In 2008, we diligently explored at least 15 different possible solutions (I'm 
not even exaggerating) for this problem.  I *hated* those redundant type 
parameters.  I was desperate to find a way to get rid of them.  The debate 
stretched out over months.  In the end, believe it or not, the last solution 
left standing happens to be exactly what you propose here, drothmaler. :-)  
Amazing.

But even though we more or less settled on this as the least-bad option, by the 
time we were left with it we just couldn't love it enough anymore to actually 
do it.  Why?

- I find the lack of symmetry disturbing. Remove the first entry? Gotta change 
the next "put" to "builder". Insert a new first entry? Make it "builder", then 
change the other "builder" to "put".  I deeply loathe APIs and style 
conventions which cause simple focused changes to bleed onto logically 
unrelated lines. (I call it the blast radius.)

- It's not that rare for the static types of k1 and v1 to be something slightly 
more specific than what the type of the map should be, so you have to upcast, 
making that .builder(k1, v1) line even more extra-specially gross.

- But it's mostly about that symmetry thing.

Original comment by kevinb@google.com on 28 Jan 2012 at 7:18

GoogleCodeExporter commented 9 years ago

Original comment by fry@google.com on 16 Feb 2012 at 7:18

GoogleCodeExporter commented 9 years ago
I'm afraid we've decided that we're not going to add yet one more way to create 
an immutable map.  I know the redundant type parameters are very depressing, 
believe me.  But we have problems of one kind or another no matter what we do.

Original comment by kevinb@google.com on 1 Mar 2012 at 11:48

GoogleCodeExporter commented 9 years ago
Issue 1166 has been merged into this issue.

Original comment by wasserman.louis on 12 Oct 2012 at 4:06

GoogleCodeExporter commented 9 years ago
Issue 1166 has been merged into this issue.

Original comment by kevinb@google.com on 12 Oct 2012 at 5:37

GoogleCodeExporter commented 9 years ago
This issue has been migrated to GitHub.

It can be found at https://github.com/google/guava/issues/<id>

Original comment by cgdecker@google.com on 1 Nov 2014 at 4:14

GoogleCodeExporter commented 9 years ago

Original comment by cgdecker@google.com on 3 Nov 2014 at 9:08