java中的2d arraylists(为什么最终的集合相同)

时间:2012-02-22 22:01:30

标签: java

我有一个2D ArrayListArrayList包含10 ArrayList个。我尝试了以下代码:

这是主要的2D ArrayList。在主ArrayList内,有10个ArrayList s:

 ArrayList<ArrayList<Items>> arrayList = new ArrayList<ArrayList<Items>>();

在这里,我尝试创建其中一个ArrayList的副本(selectedRow只是一个数字,表示我得到的ArrayList

ArrayList<Items> newList = new ArrayList<Items>(arrayList.get(selectedRow));

之后我创建了另一个ArrayList

   ArrayList<Items> changeList = new ArrayList<Items>(it.returnTheNewArrayList(newList,randomItem));

然后在另一个类中我创建了这个方法。此方法的目的是更改其中一个对象的属性。

public  ArrayList<Items> returnTheNewArrayList(ArrayList<Items> a,int item){

  int randomBin = r.nextInt(50);

    for(Items i:a){

        if(item==i.itemIds()){

            while(randomBin==i.bins()){
                randomBin = r.nextInt(50);

            }
            i.setBin(randomBin);

        }

    }
return a;

}

最后,我在2D ArrayList中设置了新的ArrayList

arrayList.set(whichList, changeList);

这是程序。我发现,当我运行此程序时,newListchangeList都是相同的。在这两个ArrayLists中,我保存了我在方法returnTheNewArrayList中所做的更改(我通过调试发现了它)。但我想只改变一个(changeList)。

我做错了什么?

3 个答案:

答案 0 :(得分:5)

列表包含对象的引用。当您致电i.setBin(...)时(可能)对对象本身进行更改。

每个列表都有一个独立的引用副本 - 所以你可以从一个列表中删除一个元素而不影响另一个 - 但它们只是 引用。

想象一下,你给了两个人剪贴板,上面有相同的家庭住址列表。一个人去了他们的剪贴板红色的每个房子名单的前门,然后第二个人访问了所有相同的房子。第二个人会看到红色的门,不是吗?这是一回事。 列表包含引用,而不是对象。

如果您希望列表完全独立,则需要使用对不同对象的引用来填充它们。

编辑:我刚刚注意到你需要更改returnTheNewArrayList方法,实际上甚至没有在第一个方法中创建新的ArrayList放置!

public ArrayList<Items> returnTheNewArrayList(ArrayList<Items> a,int item) {
    // Stuff which doesn't change the value of a...

    return a;
}

同样,a的值只是列表的引用 ...所以当你返回相同的引用时,你不会返回 new < / em> ArrayList

您真的需要了解引用和对象在Java中的工作方式 - 使用该语言绝对至关重要

答案 1 :(得分:2)

returnTheNewArrayList方法内部,首先需要克隆a。否则,您将修改原始ArrayList和原始Items。乔恩在解释原因方面做得很好,所以我不会在这里讨论。您的代码可能类似于:

ArrayList<Items> clone = new ArrayList<Items>(a.size());
for(Items item: a) clone.add(item.clone());

//modify clone here

return clone;

由于您自己编写了Items课程,因此您需要自己实施Cloneable课程。

有关详细信息,请参阅克隆方法的wikipedia page

答案 2 :(得分:0)

newList和changeList不相同(不是==),但它们的内容完全相同。

您的“Item”对象通过引用传递,这就是两个列表引用相同Items的原因。

要获得全新的引用,您应该在方法returnTheNewArrayList中创建一个新的Item实例(10个新引用的10个新实例。)

public  ArrayList<Items> returnTheNewArrayList(ArrayList<Items> a,int item){
//create a new List
ArrayList<Items> newList = new ArrayList<Items>();
int randomBin = r.nextInt(50);
    for(Items oldItem:a){
        // make a copy of Item to get a new instance of Item for the new List
        Item newItem = new Item(oldItem);
        if(item==newItem.itemIds()){

            while(randomBin==newItem.bins()){
                randomBin = r.nextInt(50);

            }
            newItem.setBin(randomBin);

        }

        newList.add(newItem);

    }
return newList;

}