Si j’ai la valeur et un
pour lequel renvoie
, comment puis-je obtenir la clé correspondante ? Ce que je dois effectuer une boucle sur la table de hachage ? Quelle est la meilleure façon de le faire ?
Réponses
Trop de publicités?Si votre structure de données a plusieurs-à-un mappage entre les clés et les valeurs que vous devez effectuer une itération sur les entrées et choisissez toutes les touches appropriées:
public static <T, E> Set<T> getKeysByValue(Map<T, E> map, E value) {
Set<T> keys = new HashSet<T>();
for (Entry<T, E> entry : map.entrySet()) {
if (value.equals(entry.getValue())) {
keys.add(entry.getKey());
}
}
return keys;
}
Dans le cas de one-to-one relation, vous pouvez retourner le premier jumelé clé:
public static <T, E> T getKeyByValue(Map<T, E> map, E value) {
for (Entry<T, E> entry : map.entrySet()) {
if (value.equals(entry.getValue())) {
return entry.getKey();
}
}
return null;
}
Dans Java 8:
public static <T, E> Set<T> getKeysByValue(Map<T, E> map, E value) {
return map.entrySet()
.stream()
.filter(entry -> entry.getValue().equals(value))
.map(entry -> entry.getKey())
.collect(Collectors.toSet());
}
Aussi, pour Goyave utilisateurs, BiMap peut être utile. Par exemple:
BiMap<Token, Character> tokenToChar =
ImmutableBiMap.of(Token.LEFT_BRACKET, '[', Token.LEFT_PARENTHESIS, '(');
Token token = tokenToChar.inverse().get('(');
Character c = tokenToChar.get(token);
Si vous choisissez d'utiliser les Communes, les Collections de la bibliothèque au lieu de la norme Java Collections de l'API, vous pouvez le faire avec facilité.
Le BidiMap interface dans les Collections de la bibliothèque est un bi-directionnelle de la carte, qui vous permet d'associer une clé à une valeur (comme les normal maps, et aussi à la carte d'une valeur à une clé, vous permettant ainsi d'effectuer des recherches dans deux directions. Comment obtenir une clé pour une valeur est prise en charge par le getKey() la méthode.
Il y a une mise en garde cependant, ces cartes ne peuvent pas avoir plusieurs valeurs mappés à des touches, et donc, sauf si votre ensemble de données 1:1 mappages entre les clés et les valeurs, vous ne pouvez pas utiliser bidimaps.
Mise à jour
Si vous voulez compter sur les Collections Java API, vous devrez vous assurer que la relation 1:1 entre les clés et les valeurs au moment de l'insertion de la valeur dans la carte. C'est plus facile à dire qu'à faire.
Une fois que vous pouvez vous assurer que l'utilisation de la entrySet() la méthode pour obtenir l'ensemble des entrées (mappings) dans la Carte. Une fois que vous avez obtenu l'ensemble, dont le type est la Carte.Entrée, itérer sur les entrées, en comparant la valeur stockée à l'encontre de l'attendre, et obtenir la clé correspondante.
Mise à jour #2
Soutien pour bidi cartes avec les génériques peut être trouvé dans Google Collections et la refonte Commons-Collections des bibliothèques (la dernière n'est pas un projet Apache). Grâce à Esko pour souligner le manque générique de soutien dans Apache Commons Collections. À l'aide de collections avec les génériques rend plus facile à gérer le code.
public class NewClass1 {
public static void main(String[] args) {
Map<Integer, String> testMap = new HashMap<Integer, String>();
testMap.put(10, "a");
testMap.put(20, "b");
testMap.put(30, "c");
testMap.put(40, "d");
for (Entry<Integer, String> entry : testMap.entrySet()) {
if (entry.getValue().equals("c")) {
System.out.println(entry.getKey());
}
}
}
}
Je pense que vos choix sont
- L'utilisation d'une carte mise en œuvre construite pour cela, comme le BiMap de google collections. Notez que google collections BiMap nécessite uniqueless de valeurs, ainsi que les clés, mais il offre des performances élevées dans les deux directions de la performance
- Gérer manuellement les deux cartes, l'une pour la clé -> valeur, et une autre carte pour la valeur ->
- Itérer sur les entrySet() et de trouver les clés qui correspondent à la valeur. C'est la méthode la plus lente, puisqu'elle nécessite une itération à travers l'ensemble de la collection, tandis que les deux autres méthodes ne nécessitent pas l'.