Lo que se hizo fue no crear una copia del mapa, sino de la referencia a ella. cuando dos referencias apuntan al mismo objeto, los cambios a uno se reflejarán en el otro.
Solución 1: Si esto fuera un mapa de algún tipo sencillo a otro, que haría esto en su lugar:
Map<SomeType, OtherType> map1 = new HashMap<SomeType, OtherType>(original);
Esto se llama un Copy Constructor. Casi todas las implementaciones estándar de Collection y Map tienen una, y por lo general es la forma más sencilla de clonar una estructura simple. Esto funciona bien siempre y cuando SomeType
y OtherType
son immutable (por ejemplo Integer
y otros tipos Number
, Boolean
, String
, pero no Colecciones, fechas, mapas, etc.) Matrices
Si no es así, como otras que responden y los comentaristas tienen señaló, también necesita copiar los valores del mapa.
Solución 2: Aquí hay una versión rápida y sucia que debe ser seguro:
Map<Integer, Map<String, Object>> original=new HashMap<Integer, Map<String,Object>>();
Map<Integer, Map<String, Object>> copy =
new HashMap<Integer, Map<String, Object>>();
for(Entry<Integer, Map<String, Object>> entry : original.entrySet()){
copy.put(entry.getKey(), new HashMap<String, Object>(entry.getValue()));
}
Pero, en realidad, me gusta la idea de Hunter de proporcionar un método de copia de profundidad. Así que aquí está la solución de 3: mi propia versión utilizando parámetros genéricos:
public static <K1, K2, V> Map<K1, Map<K2, V>> deepCopy(
Map<K1, Map<K2, V>> original){
Map<K1, Map<K2, V>> copy = new HashMap<K1, Map<K2, V>>();
for(Entry<K1, Map<K2, V>> entry : original.entrySet()){
copy.put(entry.getKey(), new HashMap<K2, V>(entry.getValue()));
}
return copy;
}
se le puede llamar así:
Map<Integer, Map<String, Object>> original=new HashMap<Integer, Map<String,Object>>();
// do stuff here
Map<Integer, Map<String, Object>> copy = deepCopy(original);
actualización
He hackeado una clase que realiza una clonación profunda para Mapas, Colecciones y Matrices (primitiva y de otro tipo). Uso:
Something clone = DeepClone.deepClone(original);
Aquí está:
public final class DeepClone {
private DeepClone(){}
public static <X> X deepClone(final X input) {
if (input == null) {
return input;
} else if (input instanceof Map<?, ?>) {
return (X) deepCloneMap((Map<?, ?>) input);
} else if (input instanceof Collection<?>) {
return (X) deepCloneCollection((Collection<?>) input);
} else if (input instanceof Object[]) {
return (X) deepCloneObjectArray((Object[]) input);
} else if (input.getClass().isArray()) {
return (X) clonePrimitiveArray((Object) input);
}
return input;
}
private static Object clonePrimitiveArray(final Object input) {
final int length = Array.getLength(input);
final Object copy = Array.newInstance(input.getClass().getComponentType(), length);
// deep clone not necessary, primitives are immutable
System.arraycopy(input, 0, copy, 0, length);
return copy;
}
private static <E> E[] deepCloneObjectArray(final E[] input) {
final E[] clone = (E[]) Array.newInstance(input.getClass().getComponentType(), input.length);
for (int i = 0; i < input.length; i++) {
clone[i] = deepClone(input[i]);
}
return clone;
}
private static <E> Collection<E> deepCloneCollection(final Collection<E> input) {
Collection<E> clone;
// this is of course far from comprehensive. extend this as needed
if (input instanceof LinkedList<?>) {
clone = new LinkedList<E>();
} else if (input instanceof SortedSet<?>) {
clone = new TreeSet<E>();
} else if (input instanceof Set) {
clone = new HashSet<E>();
} else {
clone = new ArrayList<E>();
}
for (E item : input) {
clone.add(deepClone(item));
}
return clone;
}
private static <K, V> Map<K, V> deepCloneMap(final Map<K, V> map) {
Map<K, V> clone;
// this is of course far from comprehensive. extend this as needed
if (map instanceof LinkedHashMap<?, ?>) {
clone = new LinkedHashMap<K, V>();
} else if (map instanceof TreeMap<?, ?>) {
clone = new TreeMap<K, V>();
} else {
clone = new HashMap<K, V>();
}
for (Entry<K, V> entry : map.entrySet()) {
clone.put(deepClone(entry.getKey()), deepClone(entry.getValue()));
}
return clone;
}
}
porque no es una copia del 'HashMap' sino una _ referencia_ al' HashMap', lo que significa que cualquier cambio en uno afectará al otro. Necesita realizar una _deep_ copia del 'HashMap' –