如何将HashMap复制到具有不同引用的ArrayList

时间:2013-05-11 17:39:11

标签: java object reference arraylist hashmap

我遇到了Java中对象引用的问题。这是情况。

假设我有一个名为MyObject的对象类。

class MyObject {
      Long id;
      String item;
      Integer number;
      BigDecimal bigNumber;
      //and Some getter and setter methods 
}

我们也说我有hashmap:

HashMap<Long, MyObject> myHash = new HashMap<Long, MyObject>();

我用MyObject的一些对象填充这个hashmap。

然后,当我尝试将此hashmap的所有元素复制到arrayList(使用addAll方法)时,hashmap中包含的所有对象都将复制到具有相同引用的arraylist。出于这个原因,当我尝试在hashmap中更改MyObject对象时,它也会在arrayList中更改。我不希望这样。我该如何预防?

我希望我清楚地说出问题所在。

提前致谢。

4 个答案:

答案 0 :(得分:1)

目前您只是复制引用。这样做是因为复制对象非常昂贵。

在您的情况下,您想要复制对象,因此在将它们添加到列表时需要复制每个对象。像

这样的东西
for(MyObject mo: myHash.values())
    list.add(mo.copy());

您可以通过多种方式实现复制,包括使用clone();

答案 1 :(得分:1)

我可以通过实施MyObject界面使类Cloneable克隆,请参阅Cloneable Javadoc

Java复制引用而不是对象。学习和理解这一点很重要。在您的情况下,您希望复制对象,因此您必须实现一个遍历地图的方法,复制对象,并将对这些副本的引用放入数组中。

如果您需要有关Java中克隆的更多信息,this Wikipedia page是一个很好的来源。

解决方案可能如下所示:

  • 通过实现MyObject接口使类Cloneable可克隆。 Object具有方法clone()的默认实现,它复制所有字段。在您的情况下,您有LongStringIntegerBigDecimal字段。所有这些都是不可变的,所以它们不需要自己克隆,这就是为什么你不需要在你班级的clone()方法中做任何事情。您仍需要覆盖Object.clone()才能将其公开。如果您的某个字段引用了另一个需要克隆的对象,则需要将代码添加到clone()

    class MyObject implements Cloneable {
        Long id;
        String item;
        Integer number;
        BigDecimal bigNumber;
        //and Some getter and setter methods
    
        @Override
        public MyObject clone() throws CloneNotSupportedException {
            return (MyObject)super.clone();
        }
    }
    
  • 编写一种方法,将地图中的对象复制到数组中:

    public ArrayList<MyObject> getArray() {
        ArrayList<MyObject> list = new ArrayList<MyObject>(myHash.size());
    
        for(MyObject object : myHash)
            list.add(object.clone());
    }
    

答案 2 :(得分:0)

您应创建数据副本,然后将副本与列表一起使用:

class MyObject { 
  ..

  public MyObject dupe() {
    return new MyObject(id, item, number, bigNumber, ..);
  }
}

void createList() {
  ArrayList<MyObject> list = new ArrayList<MyObject>();
  for (Map.Entry<Long, MyObject> e : map.entries())
    list.add(e.getValue().dupe());
}

答案 3 :(得分:0)

在将它们添加到arraylist之前,您需要克隆/复制MyObject。使用addAll时,只将对象引用从源集合复制到目标集合,而对象本身则不是。

ArrayList copyTo = new ArrayList()
for( MyObject current : myHash.values() )
{
   copyTo.add(copy(current));
} 


MyObject copy(MyObject o)
{
  MyObject copyObj = new MyObject();
  // set attributes here from 'o' to 'copyObj'
  return copyObj;
}