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();
}
}
答案 0 :(得分:4)
在内部,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
用于您的继续处理,这对您来说似乎最合乎逻辑。
答案 1 :(得分:3)
如果riskObject.setConditions(conditionList);
在conditionList
个实例中存储对riskObject
的引用,则调用conditionList.clear()
也会清除riskObject
所持有的列表引用的元素实例,因为它引用同一个实例。
您可以通过创建防御性副本来避免它:
public void setConditions (List<Condition> conditions)
{
this.conditions = new ArrayList<> (conditions);
}
这比将List的副本传递给setConditions
类的Risk
方法更好,因为它不依赖于使用{{1}的代码的实现类正常运行。