2012-01-28 17 views
8

Necesito obtener una colección de java HashMap sin los cambios en el mapa reflejados en la colección más adelante. Quería usar Collection.toArray() para lograr esto, pero no está funcionando. El Objeto resultante [] también está cambiando (los javadocs dicen que la matriz devuelta será "segura" ya que esta colección no mantiene referencias a esta). ¿Alguna forma simple de lograr esto?¿Cómo obtener una colección inmutable de java HashMap?

+0

No entendí claramente lo que intentas lograr. ¿Pero es LinkedHashMap lo que estás buscando? – batbaatar

+0

No ... el orden de inserción no es lo que estoy buscando. digamos que tenemos HashMap de . Hashmap.values ​​() me devolverá una colección .Ahora, cualquier cambio en HashMap se refleja en esta colección, que es el comportamiento predeterminado. Pero necesito una colección fija en la que no se reflejen los cambios en el mapa – sanre6

+0

@ sanre6 ¿Te refieres a cambios en * elementos * (objetos) contenía el HashMap, por casualidad? –

Respuesta

9

No es posible hacer esto con una sola llamada de API, necesita utilizar la clonación profunda. Los clones no se modificarán cuando realice cambios en el original. Este tema ya se discutió anteriormente en SO, ver How to clone ArrayList and also clone its contents? y Deep clone utility recomendation.

+0

Creo que esta respuesta podría ampliarse: ¿qué significa un "clon profundo" y cómo evita esto modificaciones o "referencias compartidas"? Un enlace puede ser útil ... –

+0

@Perception: Gracias por la edición. –

+0

Np, y buena respuesta. – Perception

8
+2

Sin embargo, esto no dice nada sobre la mutabilidad de los objetos * contenidos *. –

+1

Creo que el mapa inmutable de las colecciones de Google es lo que el OP está buscando. @pst: Mi lectura de la documentación me lleva a pensar que los objetos contenidos en com.google.common.collect.ImmutableMap son inmutables. –

+1

mi comprensión es también la misma –

2

puede crear una inmodificable Map

+0

Sin embargo, esto no dice nada sobre la mutabilidad de los objetos * con contenido. –

+2

Sin mencionar los cambios en el mapa original se reflejan en la copia. – Perception

+0

Creo que Justin tiene razón. el método 'unmodifiableMap' devolvería una vista de solo lectura del mapa que reflejaría cualquier cambio en el contenedor base y sanre6 no especificó que los objetos contenidos deberían ser inmutables, solo que el mapa debería ser. – Francois

2

El siguiente es todavía válida y se describe el problema observado (véase el bit de qué tipo de copia se realiza). Sin embargo, no proporciono ninguna respuesta en cómo para realizar una copia en profundidad.

En su lugar, mi sugerencia, es diseñar los objetos que serán immutable, que evita este problema por completo. En mi experiencia, esto funciona muy bien para la mayoría de los objetos triviales (es decir, los objetos que no son "contenedores") y puede simplificar el código y el razonamiento al respecto.


Desde el Javadoc para HashMap.values:

Devuelve una vista Colección de los valores contenidos en este mapa. La colección está respaldado por el mapa, por lo cambios en el mapa se reflejan en la colección, y viceversa ...

tal vez sería beneficioso crear una copia de la misma?

HashMap<K,V> map = ....; 
List<V> values = new ArrayList<V>(map.values()); 

Eso, en esencia, realiza una shallow-copy que es "ahora separar". Sin embargo, siendo una copia superficial, no se realiza clon/copia de los objetos contenidos. (Ver βнɛƨн respuesta de Ǥʋяʋиɢ si se desean deep-copy semántica: la pregunta en sí parece un poco vago al respecto.)

feliz de codificación

+0

hice lo mismo, esto no funciona. Los cambios también se reflejan en la nueva lista – sanre6

+0

@ sanre6. ¿Por "cambios" quiere decir "cambios a * los objetos ** en ** la colección *"? (A diferencia de "cambios en * la colección *"). Si es así, consulte los enlaces a copias superficiales/profundas, que explican el comportamiento observado, y la respuesta de βнɛƨн Ǥʋяʋиɢ. –

+0

sí exactamente cambia a los objetos contenidos – sanre6

0

Crea una copia superficial del mapa original poco con HashMap.clone(), a continuación, recuperar los valores colleation de ese. Esto creará nuevas referencias a los objetos en el mapa original en el momento de la llamada clone(); obviamente los cambios dentro de los objetos contenidos se reflejarán en la colección copiada. Si desea este comportamiento, su única forma es copiar los objetos del mapa en su colección deseada.