【问题标题】:How to create a copy of ArrayList<ArrayList<Arc>> to another ArrayList<ArrayList<Arc>>如何将 ArrayList<ArrayList<Arc>> 的副本创建到另一个 ArrayList<ArrayList<Arc>>
【发布时间】:2014-10-29 21:12:17
【问题描述】:

我有一个班级

public class Arc{
...
}

和2个ArrayList

ArrayList<ArrayList<Arc>> rotalar1 = new ArrayList<ArrayList<Arc>>();
ArrayList<ArrayList<Arc>> rotalar2 = new ArrayList<ArrayList<Arc>>();

我尝试将 rotalar1 复制到 rotalar2 中:

rotalar2.addAll(rotalar1);

但我有一个问题。如果我对 rotalar2 进行任何更改,它也会对 rotalar1 产生影响。我不想更改 rotalar1

这些行有问题

rotalar2.get(random1).remove(random3);
rotalar2.get(random2).remove(random4);

感谢您的宝贵时间

【问题讨论】:

  • 我建议您将数据结构包装在自己的类中。
  • @Mosman 看看我的回答,这就是你要找的。您想像现在一样制作深层副本而不是浅层副本。

标签: java arraylist copy effect


【解决方案1】:

遍历 rotalar1 并将该列表的每个列表复制到 rotalar2。您可以通过不同的方式制作副本。在第一个示例中,我使用构造函数并创建一个具有相同元素的新列表。请注意,如果您对 Arc 对象进行更改,此更改仍将在两个列表中生效。如果你不想要这个,你也必须复制你的 Arc 对象。

    ArrayList<ArrayList<Arc>> rotalar1 = new ArrayList<ArrayList<Arc>>();
    ArrayList<ArrayList<Arc>> rotalar2 = new ArrayList<ArrayList<Arc>>();

    for(ArrayList<Arc> list : rotalar1)
    {
        rotalar2.add(new ArrayList<Arc>(list));
    }

这是另一种方式,使用Collections.copy(dest,src)

    for(ArrayList<Arc> list : rotalar1)
    {
        ArrayList<Arc> copy = new ArrayList<>();
        Collections.copy(copy, list);  //or copy.addAll(list);
        rotalar2.add(copy);
    }

这个问题现在解决了:

rotalar2.get(random1).remove(random3);
rotalar2.get(random2).remove(random4);

但这仍然会在两个列表中生效:

rotalar2.get(rndList).get(rndArc).set(xvy)

如果你也想解决这个问题,你可以这样做:

    ArrayList<ArrayList<Arc>> rotalar1 = new ArrayList<ArrayList<Arc>>();
    ArrayList<ArrayList<Arc>> rotalar2 = new ArrayList<ArrayList<Arc>>();

    for(ArrayList<Arc> list : rotalar1)
    {
        ArrayList<Arc> tmpList = new ArrayList<>();
        for(Arc arcObj : list)
        {
            tmpList.add(copyOfyourArc); //TODO how do you want to creat a copy of Arc obj?
        }
        rotalar2.add(tmpList);
    }

【讨论】:

    【解决方案2】:

    方法addAll 进行浅拷贝,这意味着它将对象的所有引用(不是实际的对象)从rotalar1 复制到rotalar2

    • 一种方法,你需要遍历每个对象(Arc)并克隆 并将其添加到新列表中。
    • 另一种方法是使用序列化进行深度复制。 Example Code

    【讨论】:

      【解决方案3】:

      你没有深度复制你的列表。

      问题是,您的列表包含对对象的引用。如果您将该(列表)引用复制到您的第二个列表,则两个引用(原始引用和复制的引用)都指向同一个对象。通过第二个列表中的引用应用于对象的每个更改也将在第一个列表中可见。

      要深度复制集合,您可以例如遍历它并手动复制每个索引。

      【讨论】:

        【解决方案4】:

        您应该实现自己的方法来在 Arc 类中进行深度复制。该方法应创建对象的新实例并将所有字段(属性)设置为当前对象具有的值。此方法应返回一个新的 Arc 类型的对象,该对象与试图复制的对象具有所有相同的值。然后,您应该遍历您的数组列表并在每个对象上使用您的复制方法,并将新对象添加到一个新的数组列表中,该数组列表将是您原始数组列表的副本。示例:

        //I don't know the attributes of your Arc class this is just an example
        
        public Arc deepCopy()
        {
            Arc copyOfArc = new Arc(this.field, this.field2, this.field3, this.field4, etc...);
            //if you don't set everything in the constructor then you should use your setters here.
            copyOfArc.setField5(this.Field5);
            etc...
            return copyOfArc;
        }
        

        使用此方法遍历您的数组列表并将每个弧对象复制到一个新的数组列表。

        这是使用 deepCopy() 方法将对象复制到新数组列表的示例:

        ArrayList<ArrayList<Arc>> rotalar2 = new ArrayList<ArrayList<Arc>>();
        int counter = 0;
        
        for(ArrayList<Arc> temp : rotalar1)
        {
           rotalar2.add(new ArrayList<Arc>());
           for(Arc temp1 : temp)
           {
              rotalar2.get(counter).add(temp1.deepCopy());
           }
           counter++;
        }
        

        这将使用 deepCopy 将 arraylist rotalar1 复制到 arraylist rotalar2,因此每个 arraylist 将拥有自己的对象,并且不再相互影响。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-01-11
          • 1970-01-01
          • 2017-11-24
          • 2019-09-13
          • 2018-08-19
          • 1970-01-01
          相关资源
          最近更新 更多