Java ArrayList.clear() 方法的行为是否一致?
Does the Java ArrayList.clear() method behave consistently?
Java 中的 clear() 方法是否将 ArrayList 中的元素清空,或者只是释放其引用并保持值有效。
我正在将 ArrayList 中的所有对象分配给另一个对象,然后清除它。清除它后,对另一个对象的分配引用给出了不一致的结果。另一方面,如果我创建一个新的 ArrayList 对象而不是清除它,它就可以正常工作。
ArrayList <Condition> conditionList = new ArrayList<Condition>();
Risk riskObject = new Risk();
for (int i =0; i<10; i++) {
if(some-condition){
addElemetsToConditionList();
}else{
addElemetsToConditionList();
riskObject.setConditions(conditionList); // Setter which sets condition list to risk object.
Risk newRiskObject = new Risk();
riskObject = newRiskObject;
// conditionList = new ArrayList<Condition>();
conditionList.clear();
}
}
在内部,它 null
其后备缓冲区中的所有元素(删除它拥有的引用)并将其大小设置为 0
/**
* Removes all of the elements from this list. The list will
* be empty after this call returns.
*/
public void clear() {
modCount++;
// clear to let GC do its work
for (int i = 0; i < size; i++)
elementData[i] = null;
size = 0;
}
您可能对外部数据的任何引用仍然有效,只是 ArrayList
不再维护对它们的引用
我相信你的问题就在这里...
riskObject.setConditions(conditionList);
您正在将 ArrayList
的实例传递给 riskObject
然后清除它,它共享同一个实例。
相反,您可以创建 ArrayList
的新实例
riskObject.setConditions(new ArrayList(conditionList));
它复制了 conditionList
的内容,所以当您清除它时,您传递给 riskObject
的引用将不会受到影响,或者,正如您已经完成的那样,创建一个新的 ArrayList
供您继续处理,这对您来说似乎最合乎逻辑。
如果 riskObject.setConditions(conditionList);
在 riskObject
实例中存储对 conditionList
的引用,调用 conditionList.clear()
也会清除 [=13] 持有的列表引用的元素=] 实例,因为它指的是同一个实例。
您可以通过创建防御副本来避免它:
public void setConditions (List<Condition> conditions)
{
this.conditions = new ArrayList<> (conditions);
}
这比将 List 的副本传递给 Risk
class 的 setConditions
方法要好,因为它不依赖于使用的代码的实现Risk
class 才能正常运行。
Java 中的 clear() 方法是否将 ArrayList 中的元素清空,或者只是释放其引用并保持值有效。
我正在将 ArrayList 中的所有对象分配给另一个对象,然后清除它。清除它后,对另一个对象的分配引用给出了不一致的结果。另一方面,如果我创建一个新的 ArrayList 对象而不是清除它,它就可以正常工作。
ArrayList <Condition> conditionList = new ArrayList<Condition>();
Risk riskObject = new Risk();
for (int i =0; i<10; i++) {
if(some-condition){
addElemetsToConditionList();
}else{
addElemetsToConditionList();
riskObject.setConditions(conditionList); // Setter which sets condition list to risk object.
Risk newRiskObject = new Risk();
riskObject = newRiskObject;
// conditionList = new ArrayList<Condition>();
conditionList.clear();
}
}
在内部,它 null
其后备缓冲区中的所有元素(删除它拥有的引用)并将其大小设置为 0
/**
* Removes all of the elements from this list. The list will
* be empty after this call returns.
*/
public void clear() {
modCount++;
// clear to let GC do its work
for (int i = 0; i < size; i++)
elementData[i] = null;
size = 0;
}
您可能对外部数据的任何引用仍然有效,只是 ArrayList
不再维护对它们的引用
我相信你的问题就在这里...
riskObject.setConditions(conditionList);
您正在将 ArrayList
的实例传递给 riskObject
然后清除它,它共享同一个实例。
相反,您可以创建 ArrayList
riskObject.setConditions(new ArrayList(conditionList));
它复制了 conditionList
的内容,所以当您清除它时,您传递给 riskObject
的引用将不会受到影响,或者,正如您已经完成的那样,创建一个新的 ArrayList
供您继续处理,这对您来说似乎最合乎逻辑。
如果 riskObject.setConditions(conditionList);
在 riskObject
实例中存储对 conditionList
的引用,调用 conditionList.clear()
也会清除 [=13] 持有的列表引用的元素=] 实例,因为它指的是同一个实例。
您可以通过创建防御副本来避免它:
public void setConditions (List<Condition> conditions)
{
this.conditions = new ArrayList<> (conditions);
}
这比将 List 的副本传递给 Risk
class 的 setConditions
方法要好,因为它不依赖于使用的代码的实现Risk
class 才能正常运行。