icon definicion java generics guava

java - definicion - Forma compacta para crear Guava Multimaps?



jcombobox java (6)

Si quiero crear un nuevo Multimap con valores predeterminados simples, tengo que hacer algo como:

private final Multimap<Key, Value> providersToClasses = Multimaps .newListMultimap( new HashMap<Key, Collection<Value>>(), new Supplier<List<Value>>() { @Override public List<Value> get() { return Lists.newArrayList(); } });

porque Java no puede inferir los tipos correctos si Maps.newHashMap se usa para el mapa de respaldo. Por supuesto, esto se puede refactorizar en un método separado, pero ¿hay alguna forma de escribirlo de manera más concisa?


¿Por qué no estás usando ArrayListMultimap.create() para un caso tan simple? Es la forma predeterminada de crear el HashMap / ArrayList simple que es probablemente el multimapa más utilizado.


Aquí hay una solución compacta:

Multimap<Integer, String> multi = HashMultimap.create();


En Java 8, esto es mucho más agradable, para todo tipo de multimapas. Esto es por dos razones:

Se parece a esto:

Multimap<Key, Value> providersToClasses = Multimaps.newListMultimap(new HashMap<>(), ArrayList::new);


La documentación de Guava establece que el método de create defendido por otras respuestas "pronto será desaprobado" a favor de las diferentes formas presentadas a continuación, y por lo tanto debe evitarse.

Desde Guava 21.0 en adelante , la forma recomendada de crear un objeto Multimap donde los valores se almacenan en colecciones ArrayList es la siguiente:

MultimapBuilder.hashKeys().arrayListValues().build();

También puede usar parámetros si desea especificar el número esperado de claves en su mapa y el número esperado de valores por clave:

MultimapBuilder.hashKeys(expectedKeys).arrayListValues(expectedValuesPerKey).build();

Finalmente, puedes crear una nueva Multimap partir de una existente usando esta construcción:

MultimapBuilder.hashKeys().arrayListValues().build(multimap);

Si desea utilizar estructuras de datos distintas de ArrayLists en su Multimap , puede reemplazar la llamada a arrayListValues() por una serie de otras, enumeradas here .


Me encuentro con este problema al escribir clientes y construir mapas de parámetros de consulta. Un bonito y breve patrón que me gusta para construir mapas múltiples es usar ImmutableMultiMap#builder

Multimap<String, String> queryParams = ImmutableMultimap.<String, String>builder() .put("key-1", "value-1") .put("key-1", "value-2") .build();


Sin embargo, para responder el problema de inferencia de tipo original, también puede especificar los tipos genéricos en un método estático usando Maps.<Key, Collection<Value>>newHashMap() , pero ciertamente no es más conciso que el new HashMap<Key, Collection<Value>>() (puede ser más consistente).