Ce que vous avez fait était de ne pas créer une copie de la carte, mais la référence. lorsque deux références pointent vers le même objet, les changements à l'un refléteront dans l'autre.
Solution 1: Si cela était une carte d'un certain type simple à une autre, vous feriez ceci:
Map<SomeType, OtherType> map1 = new HashMap<SomeType, OtherType>(original);
Ceci est appelé Copy Constructor. Presque Toutes les implémentations standard de Collection et Map en ont une, et c'est généralement la manière la plus simple de cloner une structure simple. Cela fonctionne bien aussi longtemps que SomeType
et OtherType
sont immutable (par exemple Integer
et d'autres types Number
, Boolean
, String
, mais pas des collections, des dates, cartes, tableaux, etc.)
Dans le cas contraire, que d'autres answerers et commentateurs ont souligné, vous devez également copier les valeurs de la carte.
Solution 2: Voici une version rapide et sale qui devrait être en sécurité:
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()));
}
Mais en fait, j'aime l'idée de Hunter de fournir une méthode de copie en profondeur. Alors, voici Solution 3: ma propre version en utilisant des paramètres génériques:
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;
}
Vous pouvez l'appeler comme ceci:
Map<Integer, Map<String, Object>> original=new HashMap<Integer, Map<String,Object>>();
// do stuff here
Map<Integer, Map<String, Object>> copy = deepCopy(original);
Mise à jour
J'ai piraté ensemble un classe qui effectue un clonage profond pour Maps, Collections et Arrays (primitif et autre). Utilisation:
Something clone = DeepClone.deepClone(original);
Ici, il 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;
}
}
car ce n'est pas une copie du 'HashMap' c'est une référence à l'actuel' HashMap', ce qui veut dire que toute modification de l'un affectera l'autre. Vous devez effectuer une copie _deep_ du 'HashMap' –