Problème avec la Goyave est BiMap et LinkedHashMap
-
12-12-2019 - |
Question
Est-il possible dans la Goyave,
Pour effectuer une recherche inversée en
BiMap
pour les clés et les valeurs multiples?Justement, j'ai la clé et correspondant à plusieurs valeurs, je veux obtenir la clé de la valeur.Pour stocker plusieurs valeurs dans
LinkedHashMap
?Justement, je veux stocker, d'une touche de valeurs multiples dans l'ordre donc je peux obtenir la clé de la position dans la liste.
La solution
Ad.1. Oui, il est possible de faire une recherche inverse avec un BiMap<K, V>
, vous appelez simplement inverse
sur votre BiMap
et vous obtenez inversée BiMap<V, K>
vue de votre BiMap
.
Exemple (tiré de Goyave suite de test):
public void testMapConstructor() {
/* Test with non-empty Map. */
Map<String, String> map = ImmutableMap.of(
"canada", "dollar",
"chile", "peso",
"switzerland", "franc");
HashBiMap<String, String> bimap = HashBiMap.create(map);
assertEquals("dollar", bimap.get("canada"));
assertEquals("canada", bimap.inverse().get("dollar"));
}
Ad.2. En supposant que tu veux dire "Je veux stocker, clé -> plusieurs [collection] les valeurs" (Map<K, Collection<V>>
), ListMultimap
est probablement ce que vous voulez, et plus précisément ArrayListMultimap
(préserve les valeurs de l'ordre) ou LinkedListMultimap
(préserve à la fois des clés et des valeurs de l'ordre).Si votre objet est sur le point d'être immuable, je conseille fortement que vous utilisez ImmutableListMultimap
.
Vous pouvez également créer votre propre mise en œuvre de Multimap
en utilisant usine (peu clair), c'est à direJ'utilise:
private static <K, V> ListMultimap<K, V> makeLinkedArrayListMultimap() {
return Multimaps.newListMultimap(Maps.<K, Collection<V>>newLinkedHashMap(),
new Supplier<List<V>>() {
@Override public List<V> get() {
return Lists.newArrayList();
}
});
}
public static void main(final String[] args) {
final ListMultimap<String, String> multimap = makeLinkedArrayListMultimap();
multimap.putAll("one", ImmutableList.of("zero", "three"));
multimap.putAll("two", ImmutableList.of("three", "four", "three"));
multimap.putAll("three", ImmutableList.<String>of()); // note that this doesn't add key to multimap
multimap.put("four", "forty-two");
System.out.println(multimap);
// prints {one=[one, three], two=[three, four, three], four=[forty-two]}
final List<String> listForOnes = multimap.get("one");
System.out.println(listForOnes.get(0));
// prints zero
}
P. S. Jetez un oeil à Goyave wiki, qui est d'expliquer à la fois BiMap
et Multimap
.
Autres conseils
Le plus proche dans la Goyave est Multiset
pour mapper plusieurs valeurs de clé, mais je doute que cela répond à votre exigence.
- Je doute que c'est une bonne idée de chercher la clé à l'aide de valeurs (lorsque vous avez plusieurs valeurs mappé à clé unique), afin de faire de votre valeur doit être unique et compte tenu de la structure de données (qui est comme
Map<Key, Collection<Value>
) il ne peut être garanti d'avoir des valeurs uniques. - L'autre option est de goyave
BiMap
ce qui nécessite des valeurs uniques et peuvent fournir une inversion des mappages de valeur -> clé), mais puisque vous avez besoin de la carte plusieurs valeurs pour une même clé, ce d'ailleurs pas un bon ajustement.
Comme @Xaerxess dit dans sa réponse pour votre 2ème question, vous pouvez faire votre propre ListMultimap
qui utilise un LinkedHashMap
comme la sauvegarde de la carte à l'aide de la Multimaps.newListMultimap
la méthode.
Pour votre 1ère question, où vous avez les clés associé à plusieurs valeurs (c'est à direun Multimap
), vous pouvez utiliser la méthode Multimaps.invertFrom
pour créer une copie inversée de l'original de votre Multimap
faire inverse des recherches sur.Aussi, vous pouvez créer un ImmutableListMultimap
copie de l'original et de l'utilisation de son inverse()
méthode pour obtenir l'inverse, si c'est juste aller à la copie de l'original, tout comme Multimaps.invertFrom
n' (bien qu'il s'en cache, donc les appels répétés à la inverse()
de retour de la même copie.)
C'est probablement vaut le coup si vous n'avez pas l'esprit de la mémoire supplémentaire de la consommation, vont vouloir faire de multiples inverse de recherches, et n'ont pas besoin de l'inverse de la copie de rester à jour avec les modifications apportées à l'original qui se produisent après l'avoir créé.Si vous voulez juste pour la recherche de l'clés de la carte à une valeur spécifique, vous pouvez le faire en une seule itération des entrées sans créer une copie complète.