Si paso la misma clave varias veces a HashMap
's put
método, lo que ocurre con el valor original? ¿Y si incluso el valor se repite? No encontré ninguna documentación sobre esto.
Caso 1: valores sobrescritos para una clave
Map mymap = new HashMap();
mymap.put("1","one");
mymap.put("1","not one");
mymap.put("1","surely not one");
System.out.println(mymap.get("1"));
Nosotros conseguimos surely not one
.
Caso 2: valor duplicado
Map mymap = new HashMap();
mymap.put("1","one");
mymap.put("1","not one");
mymap.put("1","surely not one");
// The following line was added:
mymap.put("1","one");
System.out.println(mymap.get("1"));
Nosotros conseguimos one
.
¿Pero qué pasa con los otros valores? Estaba enseñando conceptos básicos a un estudiante y me preguntaron esto. ¿Es Map
como un cubo donde se hace referencia al último valor (pero en la memoria)?
Respuestas:
Por definición, el
put
comando reemplaza el valor anterior asociado con la clave dada en el mapa (conceptualmente como una operación de indexación de matriz para tipos primitivos).El mapa simplemente deja caer su referencia al valor. Si nada más contiene una referencia al objeto, ese objeto se vuelve elegible para la recolección de basura. Además, Java devuelve cualquier valor anterior asociado con la clave dada (o
null
si no hay ninguna presente), por lo que puede determinar qué había allí y mantener una referencia si es necesario.Más información aquí: HashMap Doc
fuente
Puede encontrar su respuesta en el javadoc de Map # put (K, V) (que en realidad devuelve algo):
Entonces, si no asigna el valor devuelto al llamar
mymap.put("1", "a string")
, simplemente no se hace referencia y, por lo tanto, es elegible para la recolección de basura.fuente
null
) como se documenta justo arriba en el javadoc, así que sí, esto es lo que quiero decir. ¿Realmente puede ser mal interpretado?El valor anterior de la clave se descarta y se reemplaza por el nuevo.
Si desea mantener todos los valores que se le dan a una clave, puede considerar implementar algo como esto:
fuente
es la función Clave / Valor y no puede tener una clave duplicada para varios valores porque cuando desea obtener el valor real de cuál de los valores pertenece a la clave ingresada
en su ejemplo cuando desea obtener el valor de "1" cuál es eso ?!
Esas son razones para tener una clave única para cada valor, pero podrías tener un truco con lib estándar de Java:
y podrías usarlo de esta manera:
y el resultado de las impresiones son:
fuente
Asocia el valor especificado con la clave especificada en este mapa. Si el mapa contenía previamente una asignación para la clave, se reemplaza el valor anterior.
fuente
Se reemplaza el valor existente en el mapa de la tecla correspondiente. Y si no existe una clave con el mismo nombre, se crea una clave con el valor proporcionado. p.ej:
Tecla OUTPUT = "1", valor = "dos"
Entonces, el valor anterior se sobrescribe.
fuente
A su pregunta si el mapa era como un cubo: no.
Es como una lista con
name=value
pares, mientrasname
que no necesita ser una cadena (aunque sí puede).Para obtener un elemento, pasa su clave al método get () que le da a cambio el objeto asignado.
Y un mapa Hash significa que si está tratando de recuperar su objeto usando el método get, no comparará el objeto real con el que proporcionó, porque necesitaría recorrer su lista y comparar () la clave Usted proporcionó el elemento actual.
Esto sería ineficiente. En cambio, no importa en qué consiste su objeto, calcula un llamado código hash de ambos objetos y los compara. Es más fácil comparar dos
int
s en lugar de dos objetos completos (posiblemente profundamente complejos). Puede imaginar el código hash como un resumen con una longitud predefinida (int), por lo tanto, no es único y tiene colisiones. Encontrará las reglas para el código hash en la documentación en la que he insertado el enlace.Si desea obtener más información al respecto, puede consultar los artículos en javapractices.com y technofundo.com
Saludos
fuente
Siempre usé:
si quisiera aplicar varias cosas a una clave de identificación.
¡siempre puedes hacer algo como esto y crear un laberinto!
fuente
Los mapas de JDK no están destinados a almacenar datos bajo claves duplicadas.
En el mejor de los casos, el nuevo valor anulará a los anteriores.
El peor escenario es la excepción (por ejemplo, cuando intenta recopilarlo como una secuencia):
No hay duplicados:
Stream.of("one").collect(Collectors.toMap(x -> x, x -> x))
Transmisión duplicada:
Stream.of("one", "not one", "surely not one").collect(Collectors.toMap(x -> 1, x -> x))
Para tratar con claves duplicadas, use otro paquete, por ejemplo: https://google.github.io/guava/releases/19.0/api/docs/com/google/common/collect/Multimap.html
Hay muchas otras implementaciones que tratan con claves duplicadas. Esos son necesarios para la web (por ejemplo, las claves de cookies duplicadas, los encabezados Http pueden tener los mismos campos, ...)
¡Buena suerte! :)
fuente
Collectors.toMap()
tiene un tercer argumento: función de fusión. Si queremos simplemente anular último elemento duplicado:Stream.of("one", "two", "one").collect(Collectors.toMap(x -> x, x -> x, (key1, key2) -> key2))
. enlace"one", "not one", "surely not one"
no producirá ningún error de clave duplicada debido a que todas las cadenas son diferentes.Por cierto, si desea alguna semántica, como poner solo si esta clave no existe. Puedes usar
concurrentHashMap
con laputIfAbsent()
función. Mira esto:https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ConcurrentHashMap.html#put(K,%20V)
concurrentHashMap
es seguro para subprocesos con alto rendimiento ya que utiliza un mecanismo de " bloqueo de bandas " para mejorar el rendimiento.fuente
Sí, esto significa que todas las teclas 1 con valor se sobrescriben con el último valor agregado y aquí agrega "seguramente no uno", por lo que mostrará solo "seguramente no uno".
Incluso si está intentando mostrar con un bucle, también mostrará solo una clave y un valor que tengan la misma clave.
fuente
Significa que el mapa hash no permitirá duplicados, si ha anulado correctamente los métodos equals y hashCode ().
HashSet también usa HashMap internamente, vea el documento fuente
fuente