Java addAll(collection) vs new ArrayList(collection)

2022-09-03 06:02:33

为什么我会有不同的行为:

  1. Collection col2 = new ArrayList(col);

  2. Collection col2 = new ArrayList();
    col2.addAll(col)

我正在与观众合作,代码很复杂,我试图解释问题的“根源”。另一个有趣的事实是下一个...

//IF i use this code i have the correct behavior in my app:
public void updateCollection(Collection<Object> col) {
    this.objectCollection.clear();
    this.objectCollection.addAll(col);
}

//IF i use this code i have unexpected behavior in my app:
public void updateCollection(Collection<Object> col) {
    this.objectCollection=new ArrayList(col);
}

答案 1

此代码的工作原理:

public void updateCollection(Collection<Object> col) {
    this.objectCollection.clear();
    this.objectCollection.addAll(col);
}

但这会带来问题:

public void updateCollection(Collection<Object> col) {
    this.objectCollection = new ArrayList(col);
}

我怀疑你的第一种方法的这种变化会带来相同的问题:

public void updateCollection(Collection<Object> col) {
    this.objectCollection = new ArrayList();
    this.objectCollection.clear();
    this.objectCollection.addAll(col);
}

为什么?显然,您在某处使用了另一个参考。在代码的某个地方,另一个对象在说(例如):objectCollection

myCopyOfObjectCollection = theOtherObject.objectCollection;

如果您使用的是 getter,这不会改变底层行为 - 您仍然保留另一个引用

因此,如果在初始赋值时,假设集合包含 {1, 2, 3},则从以下值开始:

  • this.objectCollection: {1, 2, 3}
  • that.copyOfObjectCollection: {1, 2, 3}

当您将新的 ArrayList 分配给 ,并用 {4, 5, 6} 填充它时,您会得到以下结果:this.objectCollection

  • this.objectCollection: {4, 5, 6}
  • that.copyOfObjectCollection: {1, 2, 3}

所以仍然指向原始的ArrayList。that


答案 2
Collection col2 = new ArrayList(col);

将创建一个大小为 (+10%) 的新元素,并将所有元素复制到该数组中。ArrayListcol.size()col

Collection col2 = new ArrayList();

将创建一个初始大小为 10 的新 ArrayList(至少在 Sun 实现中)。

col2.addAll(col);

如果需要,会将所有元素从 复制到 末尾,从而放大支持数组的大小。colcol2ArrayList

因此,根据您的集合大小,行为会有所不同,但不会太多。col

最好使用第一个选项 - 这将避免至少一个额外的支持阵列扩展操作。