2011-10-20 17 views
5

Tengo problemas para obtener una copia separada de mis HashMaps. Con eso quiero decir, una vez que he hecho una copia del original, hacer un cambio en uno no cambia el otro.HashMap Comportamiento de copia No puedo entender

que tienen dos HashMaps en este formato:

HashMap<String, List<String> one = new HashMap<String, List<String>(); 
HashMap<String, List<String> two = new HashMap<String, List<String>(); 

que llamo la siguiente función a continuación (getTabSetDifferences) que pasa en uno y dos, como se espera si hay algunas diferencias, esos valores se eliminarán de la HashMap y será diferente que antes de que se pasara para la prueba.

quiero que se mantienen sin cambios, por lo que intentaron passsing en:

getTabSetDifferences((HashMap)one.clone(), (HashMap)two.clone()) 

Esto todavía cambiaron los originales, así que creé dos HashMaps más en el mismo formato, y se clonaron uno y dos de ellos, he usado el nuevo hashmaps para pasar in, y el original todavía se cambió.

Luego probé:

HashMap<String, List<String>> holdOne = new HashMap<String, List<String>>(); 
holdOne.putAll(one); 

HashMap<String, List<String>> Holdtwo = new HashMap<String, List<String>>(); 
holdTwo.putAll(two); 

ahora que puedo hacer algo como:

holdTwo.remove(key); 

y el original no se cambia, pero si llamo el método con holdOne y holdTwo todavía cambia el uno y dos hashmaps originales, ¿no deberían permanecer? El método funciona, y encuentra las diferencias que quiero, y se devuelve. Pero todavía necesito los dos hashmaps originales para que sean como eran, pero no importa qué forma de llamada haga, los cambios que se hagan para sostener uno y mantener dos cambian los originales. ¿Es ese el comportamiento esperado? Si es así, ¿cuál es la forma correcta de obtener una copia de un hashmap que no esté vinculado a él.

getTabSetDifferences(holdOne, holdTwo); 

public HashMap<String, List<String>> getTabSetDifferences(HashMap<String, List<String>> hmMain, HashMap<String, List<String>> hmSecond) { 
    HashMap<String, List<String>> hmDifferences = new HashMap<String, List<String>>(); 
    for (Map.Entry<String, List<String>> entry : hmMain.entrySet()) { 
     if(hmSecond.containsKey(entry.getKey())) { 
      entry.getValue().removeAll(hmSecond.get(entry.getKey())); 
      if (entry.getValue().size() > 0) 
       hmDifferences.put(entry.getKey(), entry.getValue()); 
     } 
     else { 
      hmDifferences.put(entry.getKey(), entry.getValue()); 
     } 
    } 
    return hmDifferences; 
} 
+0

su explicación es bastante confusa. No entiendo lo que intenta hacer y cómo falla – Bozho

+0

Realmente no falla. Estoy buscando mantener mis dos HashMaps originales intactos. El método getTabSetDifferences elimina las diferencias de uno de los aprobados en HashMaps. Me gustaría pasar una copia, por lo que el original no se modifica, pero no puedo entender cómo hacer una copia, que no está vinculada al original. – Green

Respuesta

2

El método de clonación no hace una copia profunda.

Tiene 2 opciones.

  1. crear un método de copia de profundidad.
  2. Utilice una de las implementaciones Mapa del paquete java.util.concurrent como copy-on-write
+1

Escribí mi propio método de copia profunda. trabajando bien. gracias por la dirección – Green

2

Sospecho que solo está copiando las claves/valores. Esto no creará copias de las listas.

Quizás Guava's MultiMap es lo que quieres?

2

Si copia la lista como una lista (es decir, copiarlo en el ámbito lista, en lugar de alguna aplicación de nivel inferior) , entonces se verá el comportamiento del puntero ... Sin embargo, si copia de una lista a una nueva lista, esos objetos de cadena son independientes.

El método de clonación de Java no debe utilizarse a la espera de que devuelva copias distintas y profundas de un objeto: la inmutabilidad no es un concepto central de la forma en que funciona el clon.

Acepto el comentario anterior: use un multimapa en una biblioteca como guayaba, o colecciones de google, o simplemente tenga mucho cuidado con su copia y solo copie en los niveles primitivos (nunca copie una colección) y espera que sea independiente) a menos que haya probado esto de manera explícita.

Cuestiones relacionadas