Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Returning an ImmutableMap <File, File>

I have a method that returns a Map. I would initially return the HashMap that the method generated, but thought it would be better to return an ImmutableMap. Unfortunately, the following statement refuses to work in eclipse:

HashMap<File, File> map = new HashMap<File, File>();
map.put(...);
.
.
.
return ImmutableMap.builder ().putAll (map).build ();

It keeps saying that I'm returning an incompatible statement, a Map<Object, Object>.

I initially tried to use:

return ImmutableMap<File, File>.builder ().putAll (map).build ();

but that obviously didn't work. How would I best go about fixing this? Should I first store it in something like

ImmutableMap<File, File> m = ImmutableMap.builder ().putAll (map).build ();

or is there a more elegant solution?

like image 339
cesar Avatar asked Aug 07 '11 15:08

cesar


2 Answers

The correct syntax would be

return ImmutableMap.<File, File> builder().putAll(map).build();

Note that the dot is before the generics, because the generics belong to the method invocation, not the class.

As Bozho noted, you need to specify the generic types when invoking generic methods. Sometimes, you don't need to, if the compiler can infer them. But the type inference is very limited, and usually only works with method arguments, like for the copyOf method: That method is generic, but the compiler can infer the generic types from the method argument.

UPDATE : Gabriel suggested to split the statement in multiple lines, like so:

Builder<File, File> builder = ImmutableMap.builder();
builder.putAll(map);
return builder.build();

This avoids the need for the explicit type parameters in exchange for a new local variable, which IMHO does not add to readability in this case. On the other hand, if you add to the builder several times, I'd prefer the local variable over a long call chain. In the special case of only one putAll call, a copyOf instead gives the benefit of avoided type parameters in a one-liner.

like image 94
Christian Semrau Avatar answered Oct 31 '22 22:10

Christian Semrau


ImmutableMap.copyOf(map) should do.

Depending on your requirements, Collections.unmodifiableMap(map) may also fit you. The difference is that the immutable map is a copy of the original map, while the unmodifiable map is a view of the original, and if the original changes, the view will also change.

like image 45
Bozho Avatar answered Oct 31 '22 21:10

Bozho