如何在不指向 Java 源列表中的对象的情况下复制 ArrayList? [复制]
Posted
技术标签:
【中文标题】如何在不指向 Java 源列表中的对象的情况下复制 ArrayList? [复制]【英文标题】:How can i copy an ArrayList without pointing to the objects in the source List in Java? [duplicate] 【发布时间】:2020-05-15 07:24:53 【问题描述】:我的问题是我想复制一个包含对象的 ArrayList。 之后我想更改“复制列表”中的对象而不更改源列表中的对象。
我已经试过了:
ArrayList<..> copy = new ArrayList<..>(sourceList);
Collections.copy(dest, src);
更具体的问题在这里:
ArrayList<Exon> regions1 = new ArrayList<>();
regions1.add(r1);
regions1.add(r2);
regions1.add(r3);
System.out.println("Reg 1");
for (Exon e : regions1)
System.out.println(e.getStart());
ArrayList<Exon> copy = new ArrayList<>(regions1);
System.out.println("Copy");
for (Exon e : copy)
e.setStart(2);
System.out.println(e.getStart());
System.out.println("Reg 1 - untouched");
for (Exon e : regions1)
System.out.println(e.getStart());
我得到的输出是:
Reg 1
5
15
100
Copy
2
2
2
Reg 1
2
2
2
我想要的输出是:
Reg 1
5
15
100
Copy
2
2
2
Reg 1
5
15
100
【问题讨论】:
How to clone ArrayList and also clone its contents? 【参考方案1】:您只需为Exon
创建一个复制构造函数。然后在foreach
中你必须传递new Exon
对象。(with start=2)
复制构造函数:这在我们想要复制复杂的时候很有帮助 具有多个字段的对象,或者当我们想要制作深层副本时 现有对象。
1- 为
Exon
创建复制构造函数
public class Exon
private int start;
//Copy constructor
public Exon(Exon exon)
this.start = exon.getStart();
//Main Constructor and Getters and Setters
2- 从主列表创建副本
List<Exon> CopyList = mainList.stream().map(exon ->
Exon copyExon = new Exon();
copyExon.setStart(2);
return new Exon(copyExon);
).collect(Collectors.toList());
我写你的代码如下:
public static void main(String[] args)
//Initialize
ArrayList<Exon> mainList = new ArrayList<>();
Exon r1 = new Exon();
r1.setStart(5);
Exon r2 = new Exon();
r2.setStart(10);
Exon r3 = new Exon();
r3.setStart(15);
mainList.add(r1);
mainList.add(r2);
mainList.add(r3);
//Print mainList
System.out.println("Reg 1");
for (Exon e : mainList)
System.out.println(e.getStart());
//Copy the mainList (I changed your foreach)
List<Exon> copyList = mainList.stream().map(exon ->
//Create New Exon
Exon copyExon = new Exon(exon);
copyExon.setStart(2);
return copyExon ;
).collect(Collectors.toList());
//Print copyList
System.out.println("Copy");
for (Exon e : copyList)
System.out.println(e.getStart());
//Print mainList
System.out.println("Reg 1 - untouched");
for (Exon e : mainList)
System.out.println(e.getStart());
结果:
Reg 1
5
10
15
Copy
2
2
2
Reg 1 - untouched
5
10
15
This link 可能对 复制构造函数
有用【讨论】:
帖子已编辑,(Copy the mainList
部分)。【参考方案2】:
Java 中的 ArrayList 存储对对象的引用(而不是对象本身)。当您制作副本时,它会复制引用,并且两个列表都包含对相同对象的引用。所以你必须自己复制每个对象。您可以使用流来做到这一点:copy = regions1.stream().map(e->new Exon(e)).collect(Collectors.toList()).
。但是你必须实现复制构造函数public Exon(Exon src) /*copy fields from src to this*/
。也许您必须对嵌套对象做同样的事情,因为它们也被存储为 refs。
【讨论】:
以上是关于如何在不指向 Java 源列表中的对象的情况下复制 ArrayList? [复制]的主要内容,如果未能解决你的问题,请参考以下文章
如何在不替换 ES6/Javascript 中的整个属性的情况下深度复制对象 [重复]
如何在不复制数组的情况下返回 Javascript 中的数组减去单个项目? [复制]
如何在不使用 Gradle 复制 jar 的情况下将一个模块的源包含在另一个模块中?