HashMap returned by Maps.newHashMap vs new HashMap

霸气de小男生 提交于 2020-01-02 00:43:08

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!