Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HashMap returned by Maps.newHashMap vs new HashMap

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?

like image 366
Arun Manivannan Avatar asked Oct 31 '12 08:10

Arun Manivannan


People also ask

Is it better to use map or HashMap?

HashMap does not maintain any insertion order of its elements hence it is quicker than Map. In contrast to Map, HashMap can hold duplicate values. It's possible to implement the Map interface by utilizing its implementing classes. Hashmap is all about implementing the Map Interface.

What is difference between HashMap and map?

Key Differences between Map and HashMap The Map is an interface, and HashMap is a class of the Java collection framework. The Map interface can be implemented by using its implementing classes. In comparison, the HashMap class implements the Map interface. The Map contains unique key-pair values.

Why do we write map M New HashMap?

The main reason to do this is to decouple your code from a specific implementation of the interface.

What is K and V in HashMap?

Type Parameters: K - the type of keys maintained by this map V - the type of mapped values All Implemented Interfaces: Serializable, Cloneable, Map<K,V> Direct Known Subclasses: LinkedHashMap, PrinterStateReasons.


3 Answers

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)

like image 131
artbristol Avatar answered Sep 27 '22 10:09

artbristol


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.

like image 21
ford prefect Avatar answered Sep 26 '22 10:09

ford prefect


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, ?>.

like image 3
ColinD Avatar answered Sep 28 '22 10:09

ColinD