J'essaie Goyave pour la première fois et je le trouve vraiment génial.
J'exécute quelques requêtes de récupération paramétrées sur un modèle Spring jdbc. La méthode dans le DAO (AbstractDataAccessObject
) va comme ceci. Pas de problème ici.
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;
}
Voici le problème:
Quand j'appelle cette méthode en utilisant
getResultAsMap(query, new HashMap<String,Object>(ImmutableMap.of("gciList",gciList)));
cela fonctionne très bien.
Mais quand je fais ça
getResultAsMap(query, Maps.newHashMap(ImmutableMap.of("gciList",gciList)));
le compilateur s'énerve en disant
The method getResultAsMap(String, Map<String,Object>) in the type AbstractDataAccessObject is not applicable for the arguments (String, HashMap<String,List<String>>)
Est-ce que je fais quelque chose de mal ou quelle pourrait être la raison de cette plainte?
L'inférence de type échoue. Maps.newHashMap
est une méthode paramétrée statique. Cela vous permet d'utiliser
Map<String,Integer> map = Maps.newHashMap()
au lieu de
Map<String,Integer> map = new HashMap<String,Integer>()
vous évitant d'avoir à taper <String,Integer>
deux fois. En Java 7, l’opérateur losange vous permet d’utiliser
Map<String,Integer> map = new HashMap<>()
la méthode est alors redondante.
Pour répondre à votre question, utilisez simplement la version new HashMap
, car l’inférence de type ne fonctionne pas pour les paramètres de méthode. (Vous pouvez utiliser Maps.<String,Object>newHashMap()
mais cela annule le point d'utiliser la méthode)
Le problème ici est que votre méthode prend Map<String, Object>
, mais ce n'est pas ce que vous voulez réellement. Vous voulez une clé Map
of String
à any kind of values. Ce n'est pas Map<String, Object>
, c'est Map<String, ?>
.
Ajouter une réponse tardive ici:
La plupart des avantages ont disparu avant que l'inférence de type ne parvienne à Java. (yay) mais je m'interrogeais sur les différences de performances. Voici le code pour 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>();
}
C'est le même code.
Mise à jour: j'ai mal interprété l'erreur du compilateur - désolé! N'hésitez pas à supprimer ma réponse!
Quel est le type exact de "Carte" - s'agit-il vraiment de Java.util.Map et du type exact de HashMap - s'agit-il vraiment de Java.util.HashMap? Il semble y avoir une inadéquation ici.
"Réponse" d'origine: il est évident que Maps.newHashMap renvoie une implémentation de l'interface Map inconnue. Cependant, getResultAsMap requiert un HashMap (exigence inhabituelle). getResultAsMap doit être modifié pour accepter l'interface plutôt qu'une implémentation concrète.