【问题标题】:How should I go about cloning a nest ArrayList?我应该如何去克隆一个嵌套 ArrayList?
【发布时间】:2018-10-08 17:12:31
【问题描述】:

我需要写出一个方法来克隆一个嵌套的ArrayList

嵌套的ArrayList 如下所示:

ArrayList<ArrayList<Ship>> theSea = new ArrayList<ArrayList<Ship>>();

我想将它复制到一个克隆:

ArrayList<ArrayList<Ship>> seaClone = new ArrayList<ArrayList<Ship>>();

我已经尝试迭代它并复制列表:

for(int i = 0; i < theSea.size(); i++){
    seaClone.add(theSea.get(i));
}

但是,这不会克隆嵌套 ArrayList&lt;Ship&gt; 的元素,而只是复制对它的引用。

我应该如何去克隆嵌套ArrayList&lt;Ship&gt;的元素?

【问题讨论】:

  • 你的Ship 班级是什么样子的?
  • 你需要两个循环,一个迭代外部List,一个迭代内部Lists。并且不要使用clone()Cloneable since it is broken
  • 你可以在你的类Ship(深拷贝)中覆盖克隆方法。然后编写一个函数来制作 ArrayList for(Ship s : oldList) newLidt.add(s.copy()); 的深拷贝。现在你应该为所有 ArrayList 行调用这个编写的方法...
  • @0x1C1B 你可以使用clone(),但你不应该。请参阅我之前评论中的链接。
  • @Brian 为什么不试试呢?

标签: java arraylist nested bluej cloning


【解决方案1】:

类似:

ArrayList<ArrayList<Ship>> listCopy = new ArrayList<>();
for (int i=0; i<list.size(); i++) {
    ArrayList<Ship> newList = new ArrayList<>();
    for (int j=0; j<list.get(i).size(); j++) {
        newList.add(new Ship(list.get(i).get(j)));
    }
    listCopy.add(newList);
}

观察这一行:newList.add(new Ship(list.get(i).get(j)));

您需要将对象传递给构造函数并从那里复制所有属性,否则您将只创建对同一类的引用。

如果您的船舶类与此任务中的许多其他对象复杂,可能会很困难,您可以使用序列化为 json 之类的工具,然后恢复为对象或使用 java 深层对象克隆器。

【讨论】:

    【解决方案2】:

    假设Ship 对象是可克隆的:

    List<List<Ship>> clone = theSea.stream()
        .map(l -> l.stream().map(s -> (Ship)s.clone()).collect(toList()))
        .collect(toList());
    

    【讨论】:

    • @Turing85 在您(和布洛赫)看来。不是我的。有很多情况可以安全使用。
    【解决方案3】:

    但是,这不会克隆嵌套 ArrayList 的元素 而只是复制对它的引用。

    因为这实际上是您正在做的事情:您将现有对象的引用添加到新列表中。
    因此,不要为每个克隆的子列表创建一个新的嵌套 ArrayList 并在新的 Lists 中添加元素时创建新的 Ship 对象。
    例如,您可以在 Ship 中定义一个复制构造函数:

    public Ship(Ship model){     
      foo = model.foo;
      bar = model.bar;    
    }
    

    你可以这样写:

    for(List<Ship> list : theSea){
        List<Ship> currentList = new ArrayList<>();
         for(Ship ship : list){
            currentList.add(new Ship(ship));
         }
        clone.add(currentList);
      }
    

    【讨论】:

    • theSea 是一个ArrayList&lt;ArrayList&lt;Ship&gt;&gt;,因此theSea.get(i) 将返回一个ArrayList&lt;Ship&gt;
    • 构造函数无效java
    • 今天真的不是我的日子 :)
    猜你喜欢
    • 2010-10-17
    • 2011-10-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-17
    • 2013-03-28
    相关资源
    最近更新 更多