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

Java addAll(集合)与新ArrayList(集合),java,collections,arraylist,Java,Collections,Arraylist,为什么我会有不同的行为: col2=新的数组列表(col) col2=newarraylist() col2.addAll(col) 我和观众一起工作,代码很复杂,我试图解释问题的“根源”。另一个有趣的事实是下一个 //IF i use this code i have the correct behavior in my app: public void updateCollection(Collection<Object> col) { this.objectCollec

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

  • col2=新的数组列表(col)

  • col2=newarraylist()
    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);
    }
    
    //如果我使用此代码,我在我的应用程序中有正确的行为:
    公共void updateCollection(集合列){
    this.objectCollection.clear();
    this.objectCollection.addAll(col);
    }
    //如果我使用此代码,我的应用程序中会出现意外行为:
    公共void updateCollection(集合列){
    this.objectCollection=newarraylist(col);
    }
    
    将创建一个大小为
    col.size()
    (+10%)的新
    ArrayList
    ,并将
    col
    中的所有元素复制到该数组中

    Collection col2 = new ArrayList();
    
    将创建初始大小为10的新ArrayList(至少在Sun实现中)

    将所有元素从
    col
    复制到
    col2
    ArrayList
    的末尾,如有必要,放大备份数组的大小

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

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

    此代码适用于:

    public void updateCollection(Collection<Object> col) {
        this.objectCollection.clear();
        this.objectCollection.addAll(col);
    }
    
    public void updateCollection(集合列){
    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);
    }
    
    public void updateCollection(集合列){
    this.objectCollection=newarraylist(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);
    }
    
    public void updateCollection(集合列){
    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.copyofObject集合:{1,2,3}
    当您将新的ArrayList分配给this.objectCollection,并用{4,5,6}填充它时,您会得到以下结果:

    • this.objectCollection:{4,5,6}
    • that.copyofObject集合:{1,2,3}
    “that”仍然指向原始ArrayList

        public List getAdminImIdsWithValidShortNames(){
        return adminImIdsWithValidShortNames;
    }
    
    public void setAdminImIdsWithValidShortNames(List adminImIdsWithValidShortNames){
        this.adminImIdsWithValidShortNames=adminImIdsWithValidShortNames;
    }
    
    我认为,简单是美丽的,只是生成器setter/getter方法是一个好习惯。 如果先清除,然后是addAll,列表需要清除列表中的所有元素,那么addAll将是额外的备份数组扩展操作,这是不科学的


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

    请澄清,哪种行为让您感到困惑?我的代码使用a)或b)有不同的行为。在我看来,这两种操作将导致相同的结果,但显然它们不会。有些不同,你还是太含糊了。会发生什么?什么事不会发生?请在您的环境中发布一个(联合国)预期结果。您的理解有问题<代码>新阵列列表(col)
    有效。您还有另一个问题,并且没有为我们提供足够的信息来确定它可能是什么。查看您的编辑,在工作代码的情况下,您正在将信息添加到已存在的ArrayList中。对于非工作代码,您正在创建一个新代码。例如,如果另一个实体可以直接访问预先存在的ArrayList,则第二位代码不会更改该实体的副本。也许这是你的问题。