如何完全克隆一个HashMap包括 key 和 value。
我尝试枚举出里面的所有value,但Objdect类还是无法克隆。哪位有办法?

解决方案 »

  1.   

    HashMap支持clone
    应该是浅拷贝
      

  2.   

    没太明白你的意思,不过不知道下面的程序是不是能够接近一点你的意思
    public class CloneMap {    public static void main(String[] args) {
            HashMap sourceMap=new HashMap();
            HashMap destMap=null;
            sourceMap.put("key1","value1");
            sourceMap.put("key2","value2");
            destMap=(HashMap)sourceMap.clone();
            System.out.println("sourceMap: "+sourceMap);
            System.out.println("destMap:"+destMap);
        }
    }
      

  3.   

    HashMap支持clone
    应该是浅拷贝
    -----
    他的意思是可以复制key和Object但是全是引用,如果你修改其中的的值也会影响原来的Hashmap里面的值的
      

  4.   

    jFresH_MaN(听说距离产生美,所以我将离开你!) 说得对,我一个程序需要将HashMap当做参数传给某些函数,又不想让他们修改里面的值。
    暂时还没找到好办法实现。
      

  5.   

    public void method(final HashMap map) {...}
      

  6.   

    jFresH_MaN(听说距离产生美,所以我将离开你!) 说得对,我一个程序需要将HashMap当做参数传给某些函数,又不想让他们修改里面的值。
    暂时还没找到好办法实现。
    static List unmodifiableList(List list) 
              Returns an unmodifiable view of the specified list. 
    static Map unmodifiableMap(Map m) 
              Returns an unmodifiable view of the specified map. 
    static Set unmodifiableSet(Set s) 
             Returns an unmodifiable view of the specified set.
      

  7.   

    public void method(final HashMap map) {...}
    是一点用处都没有的,只是map这个引用不能变而已,对数据没有任何约束
      

  8.   

    fog628(无名)
    的方法可行,返回不可修改的试图,但是作者不要需要一份深拷贝吗?
      

  9.   

    fog628(无名)
    的方法是什么意思呀?怎么看不太明白?
      

  10.   

    呵呵,确实如此比如你原来有一个HashMap oldMap
    那么现在经过处理一下就是不可变的Map了
    Map newMap=Collections.unmodifiableMap(oldMap)
      

  11.   

    treeroot(旗鲁特) 我想在不确定HashMap.put()进去的类型时,根本没办法深拷贝,clone()是Object里的protected方法,但是HashMap.get()你不能确定返回的是什么具体类型的啊,要是可以确定HashMap中的 key和value的类型,那应该可以的
      

  12.   

    如果要深clone必须知道map里面的key和value分别是什么类的对象
    然后将这个类实现Cloneable接口
    然后在clone()方法里面实现深克隆
      

  13.   

    就是因为没法确定参数类型才使用的HashMap,呵呵。
    利用反射应该可以找到Object的类型吧。
      

  14.   

    嗯?
    怎么不行,
    HashMap mapOnlyRead = (HashMap) Collections.unmodifiableMap(map); 
    回报错!
      

  15.   

    就是因为没法确定参数类型才使用的HashMap,呵呵。
    利用反射应该可以找到Object的类型吧。
    你不能确定类型??怎么clone呢?
      

  16.   

    晕,这会报错???HashMap map = new HashMap();
    HashMap mapOnlyRead = (HashMap) Collections.unmodifiableMap(map);
      

  17.   

    问题就在这儿呀,因为不知道以后会加入什么参数,所以才使用HashMap当参数。
      

  18.   

    java.lang.ClassCastException
    at testHashMap.TestHashMap.main(TestHashMap.java:45)
      

  19.   

    HashMap map = new HashMap();Map mapOnlyRead = Collections.unmodifiableMap(map);返回的是Map不是HashMap
      

  20.   

    是呀,但map转HashMap会报错的。
    就直接拷贝你最开始那两句代码运行都会报错的。而且我把代码改成这样,仍然可以修改呀:
    Map map = new HashMap();
    map.put("date", new Date());
    Map mapOnlyRead = Collections.unmodifiableMap(map);
    Date date = (Date) mapOnlyRead.get("date");
    date.setYear(0);
    System.out.println(mapOnlyRead.get("date"));
      

  21.   

    首先key value本身必须是支持深拷贝的,一般的都不支持
      

  22.   

    为什么要把Map转为HashMap
    我从来不写这样的程序:
    HashMap map=new HashMap();
    我觉得这样很别扭,很不专业
    任何时候都是
    Map map=new HashMap();
      

  23.   

    f123(风子) 别钻牛角啊,你改东西不是用Map改,而是用Map得到一个对象的引用,再用这个引用来改
      

  24.   

    先假设value里面的都支持深拷贝吧,还是先解决这个问题吧,无名说的方法好像也不行。
      

  25.   

    如果key和value本身支持deep clone的话
    你就自己写一个方法实现clone
    public Map deepCloneMap(map src){
        Map des=new HashMap();
        for(Iterator it=src.keySet().iterator();it.hasNext();){
            Object key=it.next();
            Object value=src.get(key);
            des.put(key.clone(),value.clone());
        }
    }
      

  26.   

    treeroot(旗鲁特)
    现在的问题就是从map里得到的是一个Object,但Object不能直接用clone方法呀!fog628(无名):
    是呀,就是这个问题不能解决,所以才想用clone的。
      

  27.   

    如果不你觉得效率低下的话
    就用序列化和反序列化否则你就定义一个接口来实现你的深拷贝
    inteface DeepCloneable
      

  28.   

    import java.io.*;
    import java.util.*;class CloneHashMap{
    //深Clone Keys
    private static ArrayList cloneKeys(Set set){

    ArrayList oldList = new ArrayList(set);
    ArrayList newList = (ArrayList)oldList.clone();

    for (int i = 0; i< oldList.size() ; i++){
    //Clone到每一个Key
         newList.add(((Key)oldList.get(i)).clone());
        }
    return newList;
    }

    public static Map cloneMap(HashMap oldMap){
    Map newMap = (HashMap)oldMap.clone();

    ArrayList newKeys = cloneKeys(oldMap.keySet());
    for (int i = 0; i < newKeys.size(); i++){
         Object k = newKeys.get(i);
        
         //Clone到每一个Value
         Object v = ((Value)oldMap.get(k)).clone();
         newMap.put(k, v);
        }
        return newMap;
    }
    public static void main(String[] args) throws Exception{
    HashMap oldmap = new HashMap();
    for (int i = 0; i < 5; i++){
         oldmap.put(new Key(i), new Value(i));
        }
        System.out.println("更改值以前的HashMap:");
         System.out.println(oldmap);
         System.out.println("-----------------------------------");
        
         System.out.println("Clone出来的HashMap:");
    Map newmap = cloneMap(oldmap);
    System.out.println(newmap);
    System.out.println("-----------------------------------");

    Iterator i = newmap.keySet().iterator();
    while(i.hasNext()){
    ((Value)newmap.get(i.next())).increment();
    }

    System.out.println("更改Clone出来的HashMap中的值, 原来的旧HashMap");
    System.out.println(oldmap);
    System.out.println("-----------------------------------");

    System.out.println("更改Clone出来的HashMap中的值, 现在的新的HashMap");
    System.out.println(newmap);
        }
    }//一个用来作Value的类
    class Value implements Cloneable{
    private int value;
    Value(int i){
    this.value = i;
    }
    public void increment(){
    value *= 100;
    }
    public Object clone(){
    Object o = null;
    try{
    o = super.clone();
    }catch(CloneNotSupportedException e){
    e.printStackTrace();
    }
    return o;
    }
    public String toString(){
    return "" + value;
    }

    }
    //一个用来作Key的类
    class Key implements Cloneable{
    private int value;

    public Key(int i){
    this.value = i;
    }
    public Object clone(){
    Object o = null;
    try{
    o = super.clone();
    }catch(CloneNotSupportedException e){
    e.printStackTrace();
    }
    return o;
    }
    public boolean equals(Object o){
    return (o instanceof Key)
    &&(this.value == ((Key)o).value);
    }
    public int hashCode(){
    return this.value;
    }
    }
      

  29.   

    上面的是用了两个自己写的类,一个用来作key, 一个用来作value,大概可以实现 HashMap 的 Deep Clone
      

  30.   

    如果你已经实现了Cloneable
    des.put( ((Cloneable) key).clone(),((Cloneable)value).clone());就可以了
      

  31.   

    fog628(无名)  兄弟写的实际用处不大
    如果需要一个通用的深拷贝,可以用序列化,但是你不要觉得效率低下!我也不忍心用这种方式
    来实现的,幸好大部分情况是不需要深拷贝的.
        public static Object clone(Object src) throws IOException, ClassNotFoundException{
            if(src==null) return src;
            ByteArrayOutputStream baos=new ByteArrayOutputStream();
            ObjectOutputStream oos=new ObjectOutputStream(baos);
            oos.writeObject(src);
            ByteArrayInputStream bais=new ByteArrayInputStream(baos.toByteArray());
            ObjectInputStream ois=new ObjectInputStream(bais);        
            return ois.readObject();
        }
      

  32.   

    treeroot(旗鲁特) ( ) :
    des.put( ((Cloneable) key).clone(),((Cloneable)value).clone());
    好像也不行吧…………
      

  33.   

    上面的确实不行,这是由于Java本身的Clone机制造成的
      

  34.   

    Cloneable是个标记接口
    clone方法确实在Object中定义的
      

  35.   

    treeroot(旗鲁特)
    怎么老不上QQ了/???????当然序列化是最容易了,但。。
      

  36.   

    fog628(无名) 像你那样map放进去的必须是一个Value呀?
      

  37.   

    诸位,搬家了。
    又新发一贴,请进入看看:
    http://community.csdn.net/Expert/topic/4062/4062251.xml?temp=.1975214