Java 将Hashmap分配给Hashmap
我有一个hashmap,我想复制它作其他用途。但每当我复制并重用它时,它也会改变原来的版本。 为什么呢Java 将Hashmap分配给Hashmap,java,Java,我有一个hashmap,我想复制它作其他用途。但每当我复制并重用它时,它也会改变原来的版本。 为什么呢 do { Map<Integer, Map<String, Object>> map1 = originalMap; //at the second iteration originalMap is the same as map1 of the last iteration, //ev
do {
Map<Integer, Map<String, Object>> map1 = originalMap;
//at the second iteration originalMap is the same as map1 of the last iteration,
//eventhough the change was nog accepted;
//do something with map1 (change value);
if(change is accepted) {
originalMap = map1;
}
} while(iteration < 10);
do{
Map map1=原始地图;
//在第二次迭代时,originalMap与上一次迭代的map1相同,
//即使变更未被接受;
//使用map1(更改值)执行某些操作;
如果(接受变更){
原始地图=地图1;
}
}迭代次数<10次;
提前谢谢
public static <Integer,String, Schedule>Map<Integer, Map<String, Schedule>> deepCopy(Map<Integer, Map<String, Schedule>> original) {
Map<Integer, Map<String, Schedule>> copy = new HashMap<Integer, Map<String, Schedule>>();
for (Map.Entry<Integer, Map<String, Schedule>> entry : original.entrySet()) {
copy.put(entry.getKey(), deepCopy2(entry.getValue()));
}
return copy;
}
public static <String, Schedule>Map<String, Schedule> deepCopy2(Map<String, Schedule> original) {
Map<String, Schedule> copy = new HashMap<String, Schedule>();
for (Map.Entry<String, Schedule> entry : original.entrySet()) {
copy.put(entry.getKey(), entry.getValue());
}
return copy;
}
公共静态地图深度复制(地图原件){
Map copy=newhashmap();
对于(Map.Entry:original.entrySet()){
copy.put(entry.getKey(),deepCopy2(entry.getValue());
}
返回副本;
}
公共静态地图deepCopy2(地图原件){
Map copy=newhashmap();
对于(Map.Entry:original.entrySet()){
copy.put(entry.getKey(),entry.getValue());
}
返回副本;
}
您所做的不是创建地图的副本,而是创建对地图的引用。当两个参照指向同一对象时,对其中一个参照的更改将反映在另一个参照中
解决方案1:如果这是一个从某个简单类型到另一个简单类型的映射,您可以这样做:
Map<SomeType, OtherType> map1 = new HashMap<SomeType, OtherType>(original);
但事实上,我喜欢亨特提供深度复制方法的想法。下面是解决方案3:
使用通用参数的我自己的版本:
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;
}
这是:
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;
}
}
公共最终类深度克隆{
私有深度克隆(){}
公共静态X深度克隆(最终X输入){
如果(输入==null){
返回输入;
}else if(映射的输入实例){
返回(X)深度克隆映射((映射)输入);
}else if(集合的输入实例){
返回(X)deepCloneCollection((收集)输入);
}else if(对象[]的输入实例){
返回(X)deepCloneObjectArray((Object[])输入;
}else if(input.getClass().isArray()){
返回(X)clonePrimitiveArray((对象)输入);
}
返回输入;
}
私有静态对象clonePrimitiveArray(最终对象输入){
最终整数长度=Array.getLength(输入);
最终对象副本=Array.newInstance(input.getClass().getComponentType(),长度);
//不需要深度克隆,原语是不可变的
System.arraycopy(输入,0,复制,0,长度);
返回副本;
}
专用静态E[]DeepCloneObject数组(最终E[]输入){
最终的E[]克隆=(E[])Array.newInstance(input.getClass().getComponentType(),input.length);
for(int i=0;i
通过执行以下操作:
Map<Integer, Map<String, Object>> copy = originalMap;
Map copy=originalMap;
。。。你没有复制地图,只是创建了一个新的变量,它引用了完全相同的地图,很明显,你使用这个变量所做的更改将反映在原始地图中——它们指向内存中的相同对象。最好使用接收另一个贴图作为参数的复制原始贴图:
Map<Integer, Map<String, Object>> copy;
copy = new HashMap<Integer, Map<String, Object>>(originalMap);
地图复制;
复制=新哈希映射(原始映射);
上面的代码将创建原始地图的浅层副本,这意味着:如果您更改一个地图中元素的值,这些更改将反映在另一个地图中,但是您可以自由添加/删除其中一个地图中的元素,而另一个不会受到影响。如果这还不够好,您需要在复制地图时对地图中的元素进行深度复制。一个简单而直接的解决方案是在地图中的值上循环,然后将它们复制到地图中:
Map<Integer, Map<String, Object>> map1;
//iterate over the map copying values into new map
for(Map.Entry entry : originalMap.entrySet())
{
map1.put(entry.getKey(), new HashMap<String, Object>(entry.getValue()));
}
map1;
//迭代映射,将值复制到新映射中
对于(Map.Entry:originalMap.entrySet())
{
put(entry.getKey(),newhashmap(entry.getValue());
}
更好的解决方案是将其包装在一个方法中:
public static <K,J,V> Map<K, Map<J, V>> deepCopy(Map<K, Map<J, V>> original)
{
Map<K, Map<J, V>> copy;
//iterate over the map copying values into new map
for(Map.Entry<K, Map<J, V>> entry : original.entrySet())
{
copy.put(entry.getKey(), new HashMap<J, V>(entry.getValue()));
}
return copy;
}
公共静态地图深度复制(地图原件)
{
地图副本;
//迭代映射,将值复制到新映射中
对于(Map.Entry:original.entrySet())
{
copy.put(entry.getKey(),newhashmap(entry.getValue());
}
返回副本;
}
在您的代码中,originalMap
只是对map1
的引用。现在,它们都指向相同的键和值。请记住,这是Java,其中对象引用上的“=”只是一个引用赋值(而不是深度或浅层副本)
Java集合通常支持通过clone
或putAll
进行某种形式的浅层复制。在映射的情况下,假设map1
和map2
属于HashMap
类型,如果希望一个映射是另一个映射的浅层副本(表示一个不同的HashMap对象,但具有共享键和值),则可以执行以下操作:
HashMap<KeyType,ValueType> map1();
HashMap<KeyType,ValueType> map2();
map2.put(x1,v1); // map2 = {{x1,v1}}
map1.put(x2,v2); // map1 = {{x2,v2}}
map1 = map2.clone(); // map1 = {{x1,v1}}, with x2 and v2 gone
map2.clear();
map2.put(x3,v3); // map2 = {{x3,v3}}
map2.put(x4,v4); // map2 = {{x3,v3},{x4,v4}}
map1.put(x4,v5); // map1 = {{x1,v1}, {x4,v5}}
// add all of map2 into map1, replacing any mappings with shared keys
map1.putAll(map2); // map1 = {{x1,v1},{x3,v3},{x4,v4}}, notice how v5 is gone
HashMap map1();
HashMap map2();
map2.put(x1,v1);//微管相关蛋白2
Map<Integer, Map<String, Object>> map1;
//iterate over the map copying values into new map
for(Map.Entry entry : originalMap.entrySet())
{
map1.put(entry.getKey(), new HashMap<String, Object>(entry.getValue()));
}
public static <K,J,V> Map<K, Map<J, V>> deepCopy(Map<K, Map<J, V>> original)
{
Map<K, Map<J, V>> copy;
//iterate over the map copying values into new map
for(Map.Entry<K, Map<J, V>> entry : original.entrySet())
{
copy.put(entry.getKey(), new HashMap<J, V>(entry.getValue()));
}
return copy;
}
HashMap<KeyType,ValueType> map1();
HashMap<KeyType,ValueType> map2();
map2.put(x1,v1); // map2 = {{x1,v1}}
map1.put(x2,v2); // map1 = {{x2,v2}}
map1 = map2.clone(); // map1 = {{x1,v1}}, with x2 and v2 gone
map2.clear();
map2.put(x3,v3); // map2 = {{x3,v3}}
map2.put(x4,v4); // map2 = {{x3,v3},{x4,v4}}
map1.put(x4,v5); // map1 = {{x1,v1}, {x4,v5}}
// add all of map2 into map1, replacing any mappings with shared keys
map1.putAll(map2); // map1 = {{x1,v1},{x3,v3},{x4,v4}}, notice how v5 is gone