我正在尝试将ArrayList的内容复制到另一个并更改复制的内容。我不希望这一点反映在原文中。
我检查了SO并做了相应的更改,仍然是同样的问题。有人可以帮忙吗?我正在分享以下代码:
private ArrayList<CustVoiceListObject> FilterApprovedWorkFromList() {
ArrayList<CustVoiceListObject> arrayListCopy = new ArrayList<>(arrayListCustVoice);
for(int i =0; i<arrayListCopy.get(position).getPackageArray().size();i++)
{
if(!arrayListCopy.get(position).getPackageArray().get(i).getPackageApproved().equals("Y"))
{
arrayListCopy.get(position).getPackageArray().remove(i);
i--;
}
}
return arrayListCopy;
}
在调试时,当它即将返回时,我会检查原始的arraylist arrayListCustVoice
,但这也会被修改为arrayListCopy
我错过了什么?
更新 [遵循建议] [此问题因此不重复!]
这是我修改后的代码:
private ArrayList<CustVoiceListObject> FilterApprovedWorkFromList() {
ArrayList<CustVoiceListObject> arrayListCopy = (ArrayList<CustVoiceListObject>) arrayListCustVoice.clone();
for(int i =0; i<arrayListCopy.get(position).getPackageArray().size();i++)
{
if(!arrayListCopy.get(position).getPackageArray().get(i).getPackageApproved().equals("Y"))
{
arrayListCopy.get(position).getPackageArray().remove(i);
i--;
}
}
return arrayListCopy;
}
事实上我已经将Cloneable实现到我原来的类中,但我仍面临同样的问题。
更新2 [研究结论]
我遇到了这个link
就我而言,有2个班级。第二个是第一个子集。粘贴在下面:
public class CustVoiceListObject implements Cloneable {
private String txtSource, txtCustComment, txtCustOk, txtRepeat;
private int numberOfPackages, complaintSerial;
private ArrayList<CustomerVoicePackageListObject> packageArray;
private Double totalAmount;
//getters & setters & constructors
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
第2课:
public class CustomerVoicePackageListObject implements Cloneable {
public String packageCategory;
public String packageName;
public String partUsageFlag;
public String laborUsageFlag;
public String status;
public String isApproved;
//getters & setters & constructors
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
.clone()
必须链接到CLASS的clone()
,而不是其他地方。如果它正确的话,它将引发采取措施来解决异常,因为我在每个单独的类中实现了clone()。
所以这就是我所做的,将其修改为循环:
private CustVoiceListObject FilterApprovedWorkFromList() {
//Observe the change here. It's no more ArrayList, it's Class type
CustVoiceListObject arrayListCopy = null;
try {
arrayListCopy = (CustVoiceListObject) arrayListCustVoice.get(position).clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
for(int i =0; i<arrayListCopy.getPackageArray().size();i++)
{
if(!arrayListCopy.getPackageArray().get(i).getPackageApproved().equals("Y"))
{
arrayListCopy.getPackageArray().remove(i); //this is ArrayList<ClassType>. Nested class objects.
arrayListCopy.setTxtCustOk("OKOK"); //within the class
i--;
}
}
return arrayListCopy;
}
结果是packageArray中的更改反映在(失败)BUT,基本类中的txtCustOk的更改,副本中的更改,而不是原始(成功)中。这意味着,问题在于使用ArrayList进行克隆
如此深入的克隆需要满足以下规则:
1.无需单独复制基元。
2.原始类中的所有成员类都应该支持克隆,并且在上下文中应该调用原始类的克隆方法 所有成员类上的super.clone()。
3.如果任何成员类不支持克隆,那么在克隆方法中,必须创建该成员类的新实例并复制其全部 属性逐个归属到新成员类对象。这个新成员 类对象将在克隆对象中设置。
所以我的目标是摆脱ArrayList并将这些元素转移到这个类。这很痛苦。寻找一个简单的替代方案。
答案 0 :(得分:1)
问题是原始ArrayList
的元素是引用值,因此您只需复制对这些对象的引用,而不是对象本身(它们似乎是另一种数组)。
查看基本上处理同类问题的this问题。
答案 1 :(得分:0)
复制操作复制了原始列表 - 但不复制列表中的元素。
也就是说,如果oldList
有以下Person
个对象:
oldList
:John
,Jane
,Jude
,Joe
您已将oldList
复制到newList
:
oldList
:John
,Jane
,Jude
,Joe
newList
:John
,Jane
,Jude
,Joe
然后从John
newList
oldList
:John
,Jane
,Jude
,Joe
newList
:Jane
,Jude
,Joe
你可以看到它们是两个不同的列表。但是您不更改列表,您正在更改列表中 内的对象。如果Joe
的名称已更改为Jim
,则您需要:
oldList
:John
,Jane
,Jude
,Jim
newList
:Jane
,Jude
,Jim
你只做了所谓的“浅”副本。您想要执行“深层”复制,如here所示。
修改(至相关的“更新2”)
你的研究还远远不够,我很害怕。在你的(新)第1课:
public class CustVoiceListObject implements Cloneable {
// ints, Doubles, Strings
private ArrayList<CustomerVoicePackageListObject> packageArray;
//getters & setters & constructors
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
您只需返回super.clone()
- 让Java为您完成所有工作。这基本上做了导致你所有问题的浅拷贝!您可能还没有制作对象ICloneable
。您错过的是int
s,Double
甚至String
已成功复制,因此您无需克隆它们。但是ArrayList
s 没有克隆,所以你需要帮助它:
@Override
protected Object clone() throws CloneNotSupportedException {
// First copy the easy stuff
CustomerVoiceListObject cvlo = (CustomerVoiceListObject)super.clone();
cvlo.packageArray = new ArrayList<CustomerVoicePackageListObject>(packageArray.size()); // Make sure it's the right size
for (CustomerVoicePackageListObject cvplo: packageArray) {
cvlo.packageArray.add(cvplo.clone());
} // for
return cvlo;
} // clone()