Java addAll(集合)与新的ArrayList(集合)

时间:2010-11-21 15:31:56

标签: java collections arraylist

为什么我会使用以下方式获得不同的行为:

  1. Collection col2 = new ArrayList(col);

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

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

    //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);
    }
    

3 个答案:

答案 0 :(得分:15)

此代码有效:

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}

当你将 new ArrayList分配给this.objectCollection,并用{4,5,6}填充它时,你会得到这个:

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

“that”仍然指向原始的ArrayList。

答案 1 :(得分:5)

Collection col2 = new ArrayList(col);

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

Collection col2 = new ArrayList();

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

col2.addAll(col);

会将col中的所有元素复制到col2 ArrayList的末尾,如果需要,可以放大支持数组大小。

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

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

答案 2 :(得分:0)

    public List getAdminImIdsWithValidShortNames(){
    return adminImIdsWithValidShortNames;
}

public void setAdminImIdsWithValidShortNames(List adminImIdsWithValidShortNames){
    this.adminImIdsWithValidShortNames=adminImIdsWithValidShortNames;
}

我认为,简单就是美丽,只需发电机定位器/吸气器方法就是一个好习惯。 如果你先清除,那么addAll,列表需要清除列表中的所有元素,然后addAll将是额外的支持数组扩展操作,那不是科学。

只需更换,此变量将指向新列表,旧列表将为自动GC。