Java 如何创建不引用另一个Arraylist的Arraylist?
我知道,当您创建一个ArrayList并声明它时,您将它引用到另一个ArrayList,它只引用另一个ArrayList,因此对第二个ArrayList所做的更改将更改第一个ArrayList。但面对这个问题,我感到困惑Java 如何创建不引用另一个Arraylist的Arraylist?,java,arraylist,reference,clone,copy-constructor,Java,Arraylist,Reference,Clone,Copy Constructor,我知道,当您创建一个ArrayList并声明它时,您将它引用到另一个ArrayList,它只引用另一个ArrayList,因此对第二个ArrayList所做的更改将更改第一个ArrayList。但面对这个问题,我感到困惑 ArrayList <Productos> d3 = abd.dadesProductos(); ArrayList <Productos> dades2 = new ArrayList <Productos>(); System.out.p
ArrayList <Productos> d3 = abd.dadesProductos();
ArrayList <Productos> dades2 = new ArrayList <Productos>();
System.out.println("before clear() + size= "+d3.get(i).configurables.size());//43
dades2.add(d3.get(i));
dades2.get(dades2.size()-1).configurables.clear();
System.out.println("after clear() + size= "+d3.get(i).configurables.size());//0
同样的想法也发生了。我想这是因为我通过引用来分配ArrayList可配置文件
我试图用深度克隆做点什么,但没有成功。我根本不懂怎么用它
解决方案
dades2.add(new Productos(d3.get(i)));
因为为
Productos
创建一个新的构造函数似乎还不够,我还为Configurable
创建了一个新的构造函数,并在Productos
构造函数上用for逐个复制项。现在似乎可以了。问题不在于数组列表,而在于您的任务:
dades2.add(d3.get(i));
您的对象需要实现某种类型的clone()
函数,在该函数中,它们创建了一个新实例,其中填充了与原始实例相同的数据。
所以上面的这条线应该是
dades2.add( d3.get(i).clone() );
您可能需要研究的另一个主题是浅拷贝和深拷贝之间的区别。问题不是数组列表,而是您的任务:
dades2.add(d3.get(i));
您的对象需要实现某种类型的clone()
函数,在该函数中,它们创建了一个新实例,其中填充了与原始实例相同的数据。
所以上面的这条线应该是
dades2.add( d3.get(i).clone() );
您可能需要研究的另一个主题是浅拷贝和深拷贝之间的区别。发生这种情况的原因是您正在更改列表中的对象,而不是列表本身。这里的两个列表中都包含相同的对象,因此当您从其中一个列表中获得
get()
时,您也将获得另一个列表中包含的相同对象
解决这个问题的方法是将
Productos
类的副本插入到新数组中,而不是插入已经创建的对象。根据Productos类的复杂性,您可以创建一个复制构造函数,或者在其上实现clone()
来复制它。发生这种情况的原因是您正在更改列表中的对象,而不是列表本身。这里的两个列表中都包含相同的对象,因此当您从其中一个列表中获得get()
时,您也将获得另一个列表中包含的相同对象
解决这个问题的方法是将
Productos
类的副本插入到新数组中,而不是插入已经创建的对象。根据Productos类的复杂性,您可以创建一个复制构造函数,或者在其上实现clone()
来复制它。要创建ArrayList的独立副本,您需要对每个项进行迭代并单独克隆,同时将克隆放入新的ArrayList中。下面是一个示例,演示:
public static List<Productos> cloneList(List<Productos> list) {
List<Productos> clone = new ArrayList<Productos>(list.size());
for(Productos item: list) clone.add(item.clone());
return clone;
}
公共静态列表克隆列表(列表列表){
List clone=newarraylist(List.size());
对于(Productos项:list)clone.add(item.clone());
返回克隆;
}
要使上述方法起作用,必须使Productos对象实现可克隆接口并覆盖clone()方法。如果需要,您可以在此处阅读该过程:要创建ArrayList的独立副本,您需要迭代每个项目并单独克隆它们,并在运行时将克隆放入新的ArrayList中。下面是一个示例,演示:
public static List<Productos> cloneList(List<Productos> list) {
List<Productos> clone = new ArrayList<Productos>(list.size());
for(Productos item: list) clone.add(item.clone());
return clone;
}
公共静态列表克隆列表(列表列表){
List clone=newarraylist(List.size());
对于(Productos项:list)clone.add(item.clone());
返回克隆;
}
要使上述方法起作用,必须使Productos对象实现可克隆接口并覆盖clone()方法。如果需要的话,你可以在这里阅读这个过程:你在那里使用
i
,就像在d3中一样。获取(i)
——这些代码中的一些在for循环中吗?你的意思是复制吗?是的,我是气垫船。在我定义ArrayList时的部分和我第一次执行println
检查结果时的部分之间有一个for。可能值得考虑为您的可配置类创建一个生成器类,因为该副本构造函数的调用非常难以管理。您在其中使用的是i
,就像在d3中一样。get(i)
——这些代码中的一些是否在for循环中?您的意思是创建一个副本吗?是的,我使用气垫船。在我定义ArrayList时的部分和我第一次执行println
检查结果时的部分之间有一个for。为您的可配置类考虑一个生成器类可能是值得的,因为该副本构造函数的调用非常难以管理。假设configurables
是一个列表
,您将无法克隆由d3.get(i)返回的引用所指向的对象
那样。这就是为什么我提到了shallow/depp copy:-)据我所知,它取决于clone()的实现假设可配置文件
是一个列表
,您将无法克隆由d3.get(I)返回的引用所指向的对象
就是这样。这就是为什么我提到了shallow/depp copy:-)据我所知,它取决于clone()的实现。我曾尝试创建Productos
的副本构造函数,但同样的情况也发生了。分配时如下所示:dades2.add(newproductos(d3.get(i))代码>在对象内部,您是复制列表还是通过分配列表或创建新列表并复制列表的成员来复制列表?请参阅我关于浅/深复制的评论。我曾尝试创建Productos
的复制构造函数,但同样的情况也发生了。分配时如下所示:dades2.add(newproductos(d3.get(i))代码>在对象内部,您是复制列表还是通过分配列表或创建新列表并复制列表的成员来复制列表?请参阅我关于浅/深拷贝的评论。