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:
- Debido a que el compilador utiliza tipos de destino para la inferencia de tipo , no es necesario que proporcione argumentos de tipo explícito para el contructor de
HashMap
. - Las referencias al método Constructor se pueden usar para crear la fábrica
ArrayList
.
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).