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