我有一个包含自定义对象的列表。我想创建该List的深层副本。 这是自定义对象的类:
public class MyMemo {
private List<Uri> imageUriList;
private String commentText;
public MyMemo(){
imageUriList = new ArrayList<>();
}
public List<Uri> getImageUriList() {
return imageUriList;
}
public void setImageUriList(List<Uri> imageUriList) {
this.imageUriList = imageUriList;
}
public String getCommentText() {
return commentText;
}
public void setCommentText(String commentText) {
this.commentText = commentText;
}
}
现在我有以下情况:
List<MyMemo> parentList = new ArrayList<>();
List<MyMemo> copyList = new ArrayList<>(parentList);
parentList.get(currentMemoPosition).getImageUriList().removeAll(someOtherList.getImageUriList());
Log.e(TAG,"Total List: "+parentList.get(currentMemoPosition).getImageUriList().size()+" "+copyList.get(currentMemoPosition).getImageUriList().size());
但是,如果我对parentList
进行了任何更改,例如delete
项目中的add
或copyList
新项目。 clone()
也受影响。如何确保copyList不引用相同的内存地址。
更新
建议使用clone()
。但问题是我的自定义对象中有一个列表。我怎样才能$pdf = new FPDI('L', 'mm', array('119.888','50.038'));
$pdf->setPrintHeader(false);
$pdf->AddPage();
$page = $pdf->setSourceFile('aw_print.PDF');
$page = $pdf->ImportPage(1, 'TrimBox');
$pdf->useTemplate($page, 0, 0);
$x = 10;
$y = 10;
$style = array(
'border' => 1,
'vpadding' => 'auto',
'hpadding' => 'auto',
'fgcolor' => array(0,0,0),
'bgcolor' => false, //array(255,255,255)
'module_width' => 1, // width of a single module in points
'module_height' => 1 // height of a single module in points
);
$pdf->write2DBarcode('www.tcpdf.org', 'QRCODE,H', 10, 10, 60, 60, $style, 'N');
$pdf->Output('test.PDF', 'D');
他们?
答案 0 :(得分:6)
创建第一个列表时:
List<MyMemo> parentList = new ArrayList<>();
parentList.add(customObject1);
parentList.add(customObject2);
parentList.add(customObject3);
parentList
是自定义对象的引用列表。
将parentList
的内容复制到copyList
:
List<MyMemo> copyList = new ArrayList<>(parentList);
copyList
现在包含引用与parentList
相同的对象。如果更改parentList
中的对象,则copyList
中的对象也会更改,因为它们是同一个对象。
要创建列表的深层副本,您需要一种方法来复制一个自定义对象。您可以实现复制构造函数或克隆方法:
class CustomObject {
private String item1;
private String item2;
public CustomObject(String item1, String item2) {
this.item1 = item1;
this.item2 = item2;
}
// copy constructor
public CustomObject(CustomObject other) {
this.item1 = other.getItem1();
this.item2 = other.getItem2();
}
// clone
public CustomObject clone() {
CustomObject newObj = new CustomObject(this.getItem1(), this.getItem2());
return newObj;
}
}
然后你可以像这样复制一个对象:
CustomObject newObj = new CustomObject(existingObj);
或者像这样:
CustomObject newObj = existingObj.clone();
现在,您可以使用复制构造函数制作列表的深层副本:
List<CustomObject> copyList = new ArrayList<>();
for(CustomObject obj : parentList) {
copyList.add(new CustomObject(obj));
}
或克隆方法:
List<CustomObject> copyList = new ArrayList<>();
for(CustomObject obj : parentList) {
copyList.add(obj.clone());
}
我更喜欢使用复制构造函数。您可以阅读有关使用clone vs copy构造函数的good article by Josh Block in Effective Java。
答案 1 :(得分:4)
IMO,添加另一个arg构造函数,它将为您的Object进行深度克隆。
public class MyMemo {
MyMemo(MyMemo memo)
{
this.commentText = memo.getCommentText();
this.imageUriList = new ArrayList<>();
for (Uri uri : memo. getImageUriList())
{
this.imageUriList.add(new Uri(uri));
}
}
// rest of your code
}
现在,迭代您的父列表并克隆每个对象
List<MyMemo> parentList = new ArrayList<>();
List<MyMemo> copyList = new ArrayList<>();
for (MyMemo memo : parentList)
{
// create new instance of MyMemo and add to the list
copyList.add(new MyMemo(memo));
}
答案 2 :(得分:0)
以下所有选项都会生成浅层副本,这意味着更改一个数组中的值会影响第二个。它没有线程安全
1
List<Sth> a = new ArrayList<>();
List<Sth> b = new ArrayList<>(a);
2
`Collection.copy(a,b)`
3
ArrayList<Sth> b= (ArrayList) a.clone();
如果您应该迭代列表,并在此列表中添加元素,则创建新副本。这是深层拷贝。
答案 3 :(得分:0)
您还可以创建新列表,创建新对象并使用BeanUtils复制属性
for (MyMemo current : parentList) {
MyMemo copyCurrent = new Data();
BeanUtils.copyProperties(copyCurrent, current);
copyList.add(copyCurrent);
}
这将在列表中提供对象的深层副本。
答案 4 :(得分:0)
在Android中,如果您尝试创建深度复制对象类型ArrayList,则可以复制它们,但是当第一个列表中的对象进行任何更改时,这些更改也将反映在第二个列表中。
为此,有一个解决方案,
public class MyMemo {
private List<DemoClass> demoList;
}
MyMemo m = new Mymemo();
m.demoList(..,..,)
1. String s = Gson().toJson(m)
2.Mymemo m = Gson().fromJson(s,Mymemo.java)