web-dev-qa-db-fra.com

Un moyen compact de créer des multi-cartes de goyave?

Si je veux créer un nouveau Multimap avec des valeurs par défaut simples, je dois actuellement faire quelque chose comme:

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

car Java ne peut pas déduire les types corrects si Maps.newHashMap est utilisé pour la carte de support. Bien sûr, cela peut être refactorisé dans une méthode distincte, mais existe-t-il déjà un moyen de l'écrire de manière plus concise?

32
Alexey Romanov

Pourquoi n'utilisez-vous pas ArrayListMultimap.create() pour un cas aussi simple? C'est la façon par défaut de créer le HashMap/ArrayList simple qui est probablement le multimap le plus couramment utilisé.

54
Daniel Teply

Je rencontre ce problème lors de l'écriture de clients et de la création de cartes de paramètres de requête. Un joli motif succinct que j'aime pour construire des multi-cartes est d'utiliser ImmutableMultiMap#builder

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

La documentation de Guava indique que la méthode create préconisée par d'autres réponses "sera bientôt déconseillée" dans faveur des différentes formes présentées ci-dessous, et doit donc être évité.

À partir de Guava 21.0 , la façon recommandée de créer un objet Multimap où les valeurs sont stockées dans les collections ArrayList est la Suivant:

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

Vous pouvez également utiliser des paramètres si vous souhaitez spécifier le nombre attendu de clés dans votre carte et le nombre attendu de valeurs par clé:

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

Enfin, vous pouvez créer un nouveau Multimap à partir d'un existant en utilisant cette construction:

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

Si vous souhaitez utiliser des structures de données autres que ArrayLists dans votre Multimap, vous pouvez remplacer l'appel à arrayListValues() par un certain nombre d'autres, répertoriés ici .

9
Pyves

Voici une solution compacte:

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

En Java 8 c'est beaucoup plus agréable, pour toutes sortes de multimaps. C'est pour deux raisons:

Cela ressemble à ceci:

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

Pour répondre au problème d'inférence de type d'origine, vous pouvez également spécifier les types génériques sur une méthode statique à l'aide de Maps.<Key, Collection<Value>>newHashMap(), mais ce n'est certainement pas plus concis que new HashMap<Key, Collection<Value>>() (il peut être plus cohérent ).

2
Frank Pavageau