将Hashmap分配给Hashmap [英] Assigning Hashmap to Hashmap

查看:101
本文介绍了将Hashmap分配给Hashmap的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个我想要复制用于其他用途的hashmap。但每当我复制并重复使用它时,它也会改变原来的。
为什么会这样?

I have a hashmap which I want to copy for other use. But whenever I copy it and reuse it, it also changes the original one. Why is that?

    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);

提前致谢

    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;
}


推荐答案

你所做的不是创建地图的副本,但是对它的引用。当两个引用指向同一个对象时,对一个引用的更改将反映在另一个引用中。

What you did was not to create a copy of the map, but of the reference to it. when two references point to the same object, changes to one will reflect in the other.

解决方案1:如果这是从某个简单类型到另一个类型的Map,那么改为:

Solution 1: If this was a Map from some simple type to another, you would do this instead:

Map<SomeType, OtherType> map1 = new HashMap<SomeType, OtherType>(original); 

这称为复制构造函数。几乎所有标准的Collection和Map实现都有一个,它通常是克隆简单结构的最简单方法。
只要 SomeType OtherType immutable (例如 Integer 和其他 Number 类型, Boolean String ,但不包括收藏,日期,地图,数组等。)

This is called a Copy Constructor. Almost All standard Collection and Map implementations have one, and it's usually the simplest way to clone a simple structure. This will work fine as long as SomeType and OtherType are immutable (e.g. Integer and other Number types, Boolean, String, but not Collections, Dates, Maps, Arrays etc.)

如果没有,正如其他回答者和评论者指出的那样,你还需要复制地图值。

If not, as other answerers and commenters have pointed out, you also need to copy the map values.

解决方案2:这是一个快速的应该是安全的脏版本:

Solution 2: Here's a quick and dirty version that should be safe:

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()));
}

但实际上,我喜欢Hunter提供深度复制方法的想法。所以这里的解决方案3:
我自己的版本使用通用参数:

But actually, I like Hunter's idea of providing a deep copy method. So here's Solution 3: my own version using generic parameters:

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;
}

您可以这样称呼:

Map<Integer, Map<String, Object>> original=new HashMap<Integer, Map<String,Object>>();
// do stuff here
Map<Integer, Map<String, Object>> copy = deepCopy(original);






更新

我已经攻击了一个为地图,集合和数组(原始和其他)执行深度克隆的类。用法:

I've hacked together a class that performs deep cloning for Maps, Collections and Arrays (primitive and otherwise). Usage:

Something clone = DeepClone.deepClone(original);

这是:

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;
    }
}

这篇关于将Hashmap分配给Hashmap的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆