wake-up-neo.com

HashMap wird von Maps.newHashMap im Vergleich zur neuen HashMap zurückgegeben

Ich probiere Guava zum ersten Mal aus und finde es wirklich großartig.

Ich führe einige parametrisierte Abrufabfragen für eine Spring-JDBC-Vorlage aus. Die Methode im DAO (AbstractDataAccessObject) sieht so aus. Kein Problem hier.

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;
}

Hier ist das Problem:

Wenn ich diese Methode benutze

getResultAsMap(query, new HashMap<String,Object>(ImmutableMap.of("gciList",gciList)));

es funktioniert super.

Aber wenn ich das tue

getResultAsMap(query, Maps.newHashMap(ImmutableMap.of("gciList",gciList)));

der Compiler wird wütend

The method getResultAsMap(String, Map<String,Object>) in the type AbstractDataAccessObject is not applicable for the arguments (String, HashMap<String,List<String>>)

Mache ich etwas falsch oder was könnte der Grund für diese Beschwerde sein?

14
Arun Manivannan

Dies ist eine fehlgeschlagene Typinferenz. Maps.newHashMap ist eine statisch parametrisierte Methode. Es ermöglicht Ihnen zu verwenden

Map<String,Integer> map = Maps.newHashMap()

anstatt

Map<String,Integer> map = new HashMap<String,Integer>()

so müssen Sie <String,Integer> nicht zweimal eingeben. In Java 7 können Sie den Diamantoperator verwenden

Map<String,Integer> map = new HashMap<>()

die Methode ist dann also überflüssig.

Verwenden Sie zur Beantwortung Ihrer Frage einfach die Version new HashMap, da die Typinferenz für Methodenparameter nicht funktioniert. (Sie könnten Maps.<String,Object>newHashMap() verwenden, aber das macht den Sinn der Verwendung der Methode zunichte.)

30
artbristol

Das Problem hierbei ist, dass Ihre Methode Map<String, Object> akzeptiert, aber das ist eigentlich nicht das, was Sie wollen. Sie möchten eine Map von String Schlüsseln für beliebige Arten von Werten. Das ist nicht Map<String, Object>, es ist Map<String, ?>.

3
ColinD

Hier eine späte Antwort hinzufügen:

Der größte Teil der Vorteile entfällt, bevor die Typinferenz zu Java kam. (yay) aber ich habe mich über Leistungsunterschiede gewundert. Hier ist der Code für 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>();
  }

Es ist der gleiche Code.

2
ford prefect

Update: Ich habe den Compilerfehler falsch gelesen - sorry! Fühlen Sie sich frei, meine Antwort zu löschen!

Was ist der genaue Typ von "Map" - ist es wirklich Java.util.Map und der genaue Typ von HashMap - ist es wirklich Java.util.HashMap? Hier scheint es ein Missverhältnis zu geben.

Ursprüngliche "Antwort": Maps.newHashMap gibt offensichtlich eine Implementierung der Map-Schnittstelle zurück, die unbekannt ist, getResultAsMap erfordert jedoch eine HashMap (was eine ungewöhnliche Anforderung ist). getResultAsMap sollte überarbeitet werden, um statt einer konkreten Implementierung die Schnittstelle zu akzeptieren.

0
Sebastian