Si tengo el valor "foo"
y un valor HashMap<String> ftw
para el que se ftw.containsValue("foo")
devuelve true
, ¿cómo puedo obtener la clave correspondiente? ¿Tengo que recorrer el hashmap? ¿Cuál es la mejor manera de hacer eso?
450
public static final String TIME = "time";
yproperties.put(TIME, PbActivityJpa_.time);
Respuestas:
Si elige usar la biblioteca de Colecciones de Commons en lugar de la API estándar de Colecciones de Java, puede lograr esto con facilidad.
La interfaz BidiMap en la biblioteca de Colecciones es un mapa bidireccional, que le permite asignar una clave a un valor (como los mapas normales), y también asignar un valor a una clave, lo que le permite realizar búsquedas en ambas direcciones. La obtención de una clave para un valor es compatible con el método getKey () .
Sin embargo, existe una advertencia: los mapas bidi no pueden tener múltiples valores asignados a claves, y por lo tanto, a menos que su conjunto de datos tenga asignaciones 1: 1 entre claves y valores, no puede usar bidimaps.
Actualizar
Si desea confiar en la API de colecciones de Java, deberá asegurarse de la relación 1: 1 entre claves y valores al momento de insertar el valor en el mapa. Esto es más fácil dicho que hecho.
Una vez que pueda asegurarse de eso, use el método entrySet () para obtener el conjunto de entradas (asignaciones) en el Mapa. Una vez que haya obtenido el conjunto cuyo tipo es Map.Entry , repita las entradas, compare el valor almacenado con el esperado y obtenga la clave correspondiente .
Actualización n. ° 2
El soporte para mapas bidireccionales con genéricos se puede encontrar en Google Guava y en las bibliotecas refactorizadas de Commons-Collections (este último no es un proyecto Apache). Gracias a Esko por señalar el soporte genérico faltante en las colecciones de Apache Commons. El uso de colecciones con genéricos hace que el código sea más fácil de mantener.
fuente
Si su estructura de datos tiene una asignación de muchos a uno entre claves y valores, debe iterar sobre las entradas y elegir todas las claves adecuadas:
En caso de una relación uno a uno , puede devolver la primera clave coincidente:
En Java 8:
Además, para los usuarios de Guava, BiMap puede ser útil. Por ejemplo:
fuente
o(1)
. Si está iterando sobre los valores, matará el rendimiento. Si quieres unabetter performance
y tiene unaone-one
relación, puede usaranother map
dondevalue is a key
.filter(entry -> entry.getValue().equals(value))
con ninguna declaración sobre se hizo capacidad. Además, puede reemplazar con.filter(entry ->
Objects.equals
(entry.getValue(), value))
null
.map(entry -> entry.getKey())
.map(Map.Entry::getKey)
Alguna información adicional ... Puede ser útil para usted
El método anterior puede no ser bueno si su hashmap es realmente grande. Si su mapa de hash contiene una asignación de clave única a valor único, puede mantener un mapa de hash más que contenga la asignación de Valor a Clave.
Es decir, debes mantener dos hashmaps
En ese caso, puede usar el segundo hashmap para obtener la clave.
fuente
Creo que tus elecciones son
entrySet()
y para encontrar las claves que coinciden con el valor. Este es el método más lento, ya que requiere iterar a través de toda la colección, mientras que los otros dos métodos no lo requieren.fuente
Puede insertar la clave, el par de valores y su inverso en su estructura de mapa
El uso de map.get ("theValue") devolverá "theKey".
Es una forma rápida y sucia de hacer mapas constantes, que solo funcionarán para unos pocos conjuntos de datos seleccionados:
fuente
Decora el mapa con tu propia implementación
fuente
No hay una respuesta inequívoca, porque varias claves se pueden asignar al mismo valor. Si aplica la unicidad con su propio código, la mejor solución es crear una clase que use dos Hashmaps para rastrear las asignaciones en ambas direcciones.
fuente
Para encontrar todas las claves que se asignan a ese valor, recorra todos los pares en el hashmap, usando
map.entrySet()
.fuente
Usando Java 8:
fuente
value=="foo"
Esto no funcionará.equals
debe usarse para comparar cadenas.value
haya sido internado.Si construye el mapa en su propio código, intente juntar la clave y el valor en el mapa:
Luego, cuando tiene un valor, también tiene la clave.
fuente
Creo que esta es la mejor solución, dirección original: Java2s
Un uso fácil: si coloca todos los datos en hasMap y tiene item = "Automobile", entonces está buscando su clave en hashMap. Esa es una buena solución.
fuente
Me temo que solo tendrá que iterar su mapa. Lo más corto que se me ocurrió:
fuente
fuente
Parece que la mejor manera es iterar sobre las entradas usando,
map.entrySet()
ya quemap.containsValue()
probablemente lo haga de todos modos.fuente
Para el desarrollo de Android dirigido a API <19, la solución de relación uno a uno Vitalii Fedorenko no funciona porque
Objects.equals
no está implementada. Aquí hay una alternativa simple:fuente
Puedes usar lo siguiente:
fuente
Sí, debe recorrer el hashmap, a menos que implemente algo similar a lo que sugieren estas diversas respuestas. En lugar de jugar con el entrySet, solo obtendría el keySet (), iterar sobre ese conjunto y mantener la (primera) clave que le da su valor coincidente. Si necesita todas las claves que coinciden con ese valor, obviamente tiene que hacer todo.
Como sugiere Jonas, esto podría ser lo que está haciendo el método contiene valor, por lo que puede omitir esa prueba por completo y hacer la iteración cada vez (o tal vez el compilador ya eliminará la redundancia, quién sabe).
Además, en relación con las otras respuestas, si su mapa inverso parece
puede lidiar con asignaciones de clave-> valor no únicas, si necesita esa capacidad (desentrañándolas a un lado). Eso incorporaría bien a cualquiera de las soluciones que las personas sugieren aquí usando dos mapas.
fuente
Puede obtener la clave utilizando valores utilizando el siguiente código.
fuente
fuente
String
como clave y valor. Cuando llamomap.add("1", "2"); map.add("1","3");
, puedo llamarmap.getKey("2");
y recuperar"1"
, aunque"1"
sea la clave"3"
.getValue("1")
volverán3
.En java8
fuente
fuente
fuente
fuente
fuente
Use una envoltura delgada: HMap
fuente
Mis 2 centavos Puede obtener las claves en una matriz y luego recorrerla en bucle. Esto afectará el rendimiento de este bloque de código si el mapa es bastante grande, en el que primero obtiene las claves en una matriz que puede consumir algo de tiempo y luego está haciendo un bucle. De lo contrario, para mapas más pequeños, debería estar bien.
fuente
Creo que keySet () puede ser bueno para encontrar la asignación de claves al valor y tener un mejor estilo de codificación que entrySet () .
Ex:
Suponga que tiene un mapa HashMap , ArrayList res , un valor en el que desea encontrar toda la asignación de claves , luego almacene las claves en la resolución .
Puedes escribir el código a continuación:
en lugar de usar entrySet () a continuación:
Espero eso ayude :)
fuente
map.get(key) == value
no es una buena idea al verificar la igualdad de objetos, ya que está comparando referencias. La igualdad de objetos siempre debe usar su.equals()
Si bien esto no responde directamente a la pregunta, está relacionado.
De esta manera, no necesita seguir creando / iterando. Simplemente cree un mapa inverso una vez y obtenga lo que necesita.
fuente
Es importante tener en cuenta que desde esta pregunta, Apache Collections admite BidiMaps genéricos . Entonces, algunas de las respuestas más votadas ya no son precisas en ese punto.
Para un BidiMap serializado que también admite valores duplicados (escenario 1 a muchos), también considere MapDB.org .
fuente
Si desea obtener la clave del valor, lo mejor es usar bidimap (mapas bidireccionales), puede obtener la clave del valor en el tiempo O (1).
Pero, el inconveniente de esto es que solo puede usar un conjunto de claves y valores únicos.
Hay una estructura de datos llamada Table en java, que no es más que un mapa de mapas como
Tabla <A, B, C> == mapa <A, mapa <B, C>>
Aquí puede obtener
map<B,C>
mediante consultasT.row(a);
, y también puede obtenermap<A,C>
mediante consultasT.column(b);
En su caso especial, inserte C como una constante.
Entonces, es como <a1, b1, 1> <a2, b2, 1>, ...
Entonces, si encuentra a través de T.row (a1) ---> devuelve el mapa de -> get keyset this map devuelto.
Si necesita encontrar el valor clave, T.column (b2) -> devuelve el mapa de -> obtiene el conjunto de claves del mapa devuelto.
Ventajas sobre el caso anterior:
fuente