问题
I am trying Guava for the first time and I find it really awesome.
I am executing few parameterized retrieve queries on a Spring jdbc template. The method in the DAO (AbstractDataAccessObject
) goes like this. No problem here.
public Map<String,Object> getResultAsMap(String sql, Map<String,Object> parameters) {
try {
return jdbcTemplate.queryForMap(sql, parameters);
} catch (EmptyResultDataAccessException e) {
//Ignore if no data found for this query
logger.error(e.getMessage(), e);
}
return null;
}
Here's the problem :
When I call this method using
getResultAsMap(query, new HashMap<String,Object>(ImmutableMap.of("gciList",gciList)));
it works great.
But when I do this
getResultAsMap(query, Maps.newHashMap(ImmutableMap.of("gciList",gciList)));
the compiler gets upset saying
The method getResultAsMap(String, Map<String,Object>) in the type AbstractDataAccessObject is not applicable for the arguments (String, HashMap<String,List<String>>)
Am I doing something wrong or what could be the reason for this complaint?
回答1:
This is type inference failing. Maps.newHashMap
is a static parameterized method. It allows you to use
Map<String,Integer> map = Maps.newHashMap()
instead of
Map<String,Integer> map = new HashMap<String,Integer>()
saving you from having to type <String,Integer>
twice. In Java 7, the diamond operator allows you to use
Map<String,Integer> map = new HashMap<>()
so the method is then redundant.
To answer your question, just use the new HashMap
version, since type inference doesn't work for method parameters. (You could use Maps.<String,Object>newHashMap()
but that defeats the point of using the method)
回答2:
The problem here is that your method takes Map<String, Object>
, but that's not actually what you want. You want a Map
of String
keys to any kind of values. That's not Map<String, Object>
, it's Map<String, ?>
.
回答3:
Adding a late answer here:
Most of the benefit is gone before type inference came to java. (yay) but I was wondering about any performance differences. Here is the code for google.common.collect.maps
/**
* Creates a <i>mutable</i>, empty {@code HashMap} instance.
*
* <p><b>Note:</b> if mutability is not required, use {@link
* ImmutableMap#of()} instead.
*
* <p><b>Note:</b> if {@code K} is an {@code enum} type, use {@link
* #newEnumMap} instead.
*
* @return a new, empty {@code HashMap}
*/
public static <K, V> HashMap<K, V> newHashMap() {
return new HashMap<K, V>();
}
Its the same code.
回答4:
Update: I misread the compiler error - sorry! Feel free to delete my answer!
What is the exact type of "Map" - is it really java.util.Map and the exact type of HashMap - is it really java.util.HashMap? There seems to be a mismatch here.
Original "answer": Obviously Maps.newHashMap returns an implementation of the Map interface, which is unknown, however getResultAsMap requires a HashMap (which is an unusual requirement). getResultAsMap should be refactored to accept the interface, rather than a concrete implementation, instead.
来源:https://stackoverflow.com/questions/13153609/hashmap-returned-by-maps-newhashmap-vs-new-hashmap