在Java / processing中如何清空数组

60
除了遍历数组中的每个元素并将其设置为 null 之外,Java / processing 中是否有本地函数可以简单地清空一个数组(或销毁它,以便能够将其重新声明为新数组)?

float[] xco = new float[1024]; - ina
2
Java的设计使你不必担心这个问题。你应该能够安排好你的代码,以便你不需要做任何事情。对于那些可能有所影响的少数例子,它们可以很容易地重构,因此不需要这样做。 - Peter Lawrey
1
这里的问题对我来说不太清楚。您是在问1)如何将数组中的所有元素设置为null,还是2)如何从数组中删除所有元素?如果数组中的元素不再需要,并且您想要一个空数组(即一个具有零个元素的数组),以便再次使用,则可以使用myArray.clear();myArray = new ArrayList();。如果您希望数组中的每个元素都为null以满足代码中的某些特定需求,则这不是一个空数组;它是一个由null组成的数组。我已经对这个问题进行了反对投票,但如果您解决我的问题,我会改为支持它。 - Jason
8个回答

87

这里有内容

Arrays.fill(myArray, null);

并没有什么不同于您自己执行的操作(它只是循环遍历每个元素并将其设置为null)。它不是原生的,因为它是执行此操作的纯Java代码,但如果可能这是您所指的,它是一个库函数。

当然,这不能让你调整数组大小(到零),如果你所说的“空”是指这个。数组大小是固定的,因此如果您想要“新”的数组具有不同的维度,您最好就像其他答案所示重新分配对新数组的引用。更好的方法是使用像ArrayList这样的List类型,它可以具有可变大小。


4
@jjnguy: 当然。将数组清零比创建一个新的数组要高效得多(特别是当JLS需要新数组被清零时)。实际上,这正是OpenJDK的ArrayList.clear()所做的:它将大小设置为零,然后迭代整个数组,将每个索引清零。 - Mark Peters
这对我来说无法编译。错误:无法解析方法fill(boolean [],null) - IgorGanapolsky
2
如果你有一个 boolean[],你应该调用 fill(boolean[], boolean),而不是 fill(Object[], Object),因此它不会接受第二个参数为 null(因为 null 不能赋值给 boolean)。 - Mark Peters
它没有适用于 T[] 的重载。 - M.kazem Akhgary
这不适用于char[]。根据Oracle的解决方案:Arrays.fill(myCharArray,'0'); - Anonymous
显示剩余5条评论

41

你可以简单地将null分配给引用。(这对于任何类型的数组都适用,不仅仅是ints

int[] arr = new int[]{1, 2, 3, 4};
arr = null;

这将“清空”数组。如果需要,您也可以将新数组分配给该引用:

int[] arr = new int[]{1, 2, 3, 4};
arr = new int[]{6, 7, 8, 9};

如果你担心内存泄漏,不必担心。垃圾回收器将清理数组留下的任何引用。

另一个例子:

float[] arr = ;// some array that you want to clear
arr = new float[arr.length];
这将创建一个新的float[],并初始化为float类型的默认值。

1
当我将一个数组赋值为空时,我会收到NullPointerException错误...这个想法是在每次迭代中重复使用同一个数组,但是每次迭代后数字都不重要,所以可以清空它。 - ina
2
不太安全,因为它会破坏使用该数组的所有代码,并抛出“NullPointerException”。 - Jack
2
@ina,如果你将null赋值给数组,那么你将无法再使用它。你需要重新声明一个数组来引用它。请参考我的第二个例子。 - jjnguy
@ina,或者,看看我的第三个例子。 - jjnguy
2
我使用了 arr = new int[]{}; 来清空我的数组,而不是将其设为 null - Senura Dissanayake
这并不是最优的解决方案,特别是当数组很大时,为数组分配新内存会带来一些成本。最佳解决方案是用零填充数组。 - M.kazem Akhgary

8
array = new String[array.length];

这将使用所有默认值来初始化,是吗?在这种情况下,它们都是null? 但是,这不会增加NullPointerException的机会吗? - Mr. Jain

5

以双重数组为例,如果初始输入的values数组不为空,下面的代码片段在时间复杂度上优于传统的直接for-loop

public static void resetValues(double[] values) {
  int len = values.length;
  if (len > 0) {
    values[0] = 0.0;
  }
  for (int i = 1; i < len; i += i) {
    System.arraycopy(values, 0, values, i, ((len - i) < i) ? (len - i) : i);
  }
}

4
如果数组 xco 不是 final,那么一个简单的重新赋值就可以解决问题:
即:
xco = new Float[xco .length];

这里假设你需要保持数组xco的大小不变。如果没有这个要求,那么可以创建一个空数组:
xco= new Float[0];

3
比使用Arrays.fill更快的清除方式是使用这个(来自Fast Serialization Lib)。我只是使用arrayCopy(本地方法)来清空数组:
static Object[] EmptyObjArray = new Object[10000];

public static void clear(Object[] arr) {
    final int arrlen = arr.length;
    clear(arr, arrlen);
}

public static void clear(Object[] arr, int arrlen) {
    int count = 0;
    final int length = EmptyObjArray.length;
    while( arrlen - count > length) {
        System.arraycopy(EmptyObjArray,0,arr,count, length);
        count += length;
    }
    System.arraycopy(EmptyObjArray,0,arr,count, arrlen -count);
}

2
我想在Mark的评论中添加一些内容。如果你想重复使用数组而不进行额外的分配,只需再次使用它并用新值覆盖现有值即可。如果您按顺序填充数组,则此方法有效。在这种情况下,只需记住最后一个初始化的元素,并使用该数组直到此索引。数组末尾存在一些垃圾并不重要。

这正是 ArrayList 在幕后为您完成的工作。自己手动实现虽然可行,但更加繁琐且容易出错。在我看来,最好使用 Collection 类。但如果您必须直接使用数组,则这是一个很好的观察结果。 - Mark Peters

-1
我用以下两行代码实现了这个功能,我有一个名为selected_items的数组,用于获取dataTable上所有选定的项目。
selected_items = null;
selected_items = [];

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接