0

我有许多以全局 ArrayList 作为参数的函数,其中一些函数不会对该列表进行任何更改,而其他函数则需要在工作时删除该数组的某些元素,因此我在这些函数中创建了一个本地 tempArrays。

static ArrayList array1 = new ArrayList();

public fn1(ArrayList array1)
{
   ArrayList tempArray1 = new ArrayList();
   tempArray1 = array1;
   tempArray1.remove(elemnt);
}

问题是删除的元素也从原始 arrayList 中删除array1,我不知道为什么?.

谢谢..

4

8 回答 8

6

排队 :

tempArray1 = array1;

您正在使变量引用所tempArray1引用的同一对象。因此两者都引用 的同一个对象。使用任何变量对对象所做的任何更改都将由两个变量反映出来。因此,当您使用以下方法删除元素时:ArrayListarray1ArrayListArrayList

tempArray1.remove(elemnt);

array1也反映了元素的去除。

你应该使用:

ArrayList tempArray1 = new ArrayList(array1);

如官方文档中所述ArrayList(Collection<? extends E> c)::

按照集合的迭代器返回的顺序构造一个包含指定集合元素的列表。

参数: c -将其元素放入此列表的集合

于 2013-04-27T19:29:20.867 回答
4

问题是声明tempArray1 = array1;只是tempArray1引用array1. 要创建真正的副本,请调用:

ArrayList tempArray1 = new ArrayList(array1);
于 2013-04-27T19:29:43.143 回答
2

我认为您误解了 Java 的一些特性:

  1. 当你声明一个 Java 变量时,它是一个对象的引用,就像 C/C++ 中的一个指针。它可以是对以前创建的对象的引用,也可以创建一个新对象来引用。

    //Created a new object instance on heap
    ArrayList tempArray1 = new ArrayList();
    //Both tempArray1 and tempArray2 will point to same object in memory
    ArrayList tempArray2 = tempArray1;
    

    在您的代码中,您首先创建一个新的ArrayList对象引用tempArray1并为其创建一个新对象,然后ArrayList tempArray1 = new ArrayList();通过tempArray1 = array1;. 因此,您创建的第一个对象没有指向它的引用,将被删除。现在 tempArray1 和 tempArray2 都指向同一个对象。

  2. 在Java中如果你想复制一个对象,clone如果它实现了Clonable接口,你可以使用它的方法。另请查看此问题以获取有关克隆的详细答案How do I copy an object in Java? 所以你想复制你的数组,但你做错了。

于 2013-04-27T20:45:33.223 回答
2

尝试执行以下操作

List tempList = new ArrayList(oldArrayList);
于 2013-04-27T19:29:11.370 回答
2

从原始项目中删除该项目的原因ArrayList是,在 Java 中,引用类型(数组、字符串和任何其他属于 的子类Object)的变量包含引用,而不是值。这本质上意味着一个类型的变量ArrayList保存ArrayList分配数据的内存地址。当你这样做时tempArray1 = array1;,你只是给出tempArray1了相同的地址ArrayList。这一切都只适用于从 Java 派生的类型,如果你不知道的话Object,它恰好包含。原始类型 ( , , , , , , ) 存储为值。Stringbyteshortintlongcharfloatdouble

现在,解决你真正的问题;我必须问,为什么你不只是使用该get(index)方法来处理该项目?

如果您需要实际删除元素,请使用 的复制构造函数ArrayList,如下所示: ArrayList tempArray1 = new ArrayList(array1);

于 2013-04-27T19:34:39.883 回答
1

A)tempArray1是一个变量,它引用与相同的实例array1。要进行复制,请使用复制构造函数:

List tempArray1 = new ArrayList(tempArray1);

B) 从方法中删除参数。无需传入列表 - 方法中的代码已经可以访问列表。事实上,通过使用具有相同名称的参数将其传入,您正在隐藏原始列表 - 如果传入不同的列表,您将使用该列表而不是您认为正在使用的列表。

C) 您应该 输入您的列表,例如:

static ArrayList<String> array1 = new ArrayList<String>();

D)始终使用抽象类:将其更改为 List:

static List<String> array1 = new ArrayList<String>();

E)列表不是数组,所以不要调用变量“array1”——它会误导:

static List<String> list1 = new ArrayList<String>();
于 2013-04-27T19:53:44.700 回答
1

您还可以使用 addAll(Collection c) 方法

static ArrayList array1 = new ArrayList();

public fn1(ArrayList array1)
{
   ArrayList tempArray1 = new ArrayList();
   tempArray1.addAll(array1);
   tempArray1.remove(elemnt);
}
于 2013-04-27T19:36:27.487 回答
1

您正在用全局实例替换您创建的实例。试试这个:

ArrayList tempArray1 = new ArrayList(array1);
tempArray1.remove(elemnt);
于 2013-04-27T19:33:16.040 回答