从数组中删除项目和收缩数组

2022-09-01 03:08:15

如何从数组中删除项目,然后将数组大小调整为较小的大小?同样,如果我需要添加其他项目,如何增加容量?


答案 1

分配 Java 数组时,它的大小是固定的,并且不能更改。

  • 如果要“增长”或“收缩”现有数组,则必须分配适当大小的新数组并复制数组元素;例如,使用 或 .复制循环也可以工作,尽管它看起来有点笨拙...国际 海事 组织。System.arraycopy(...)Arrays.copyOf(...)

  • 如果要从数组中“删除”一个或多个项目(在真正意义上...而不仅仅是将它们替换为 ),您需要分配一个新的较小的数组,并在要保留的元素之间复制。null

  • 最后,您可以通过赋值来“擦除”引用类型数组中的元素。但这带来了新的问题:null

    • 如果您使用元素来表示某些内容,则无法执行此操作。null
    • 现在,所有使用数组的代码都必须以适当的方式处理元素的可能性。错误的复杂性和潜在性更高 1.null

有第三方库形式的替代方案(例如Apache Commons),但您可能要考虑是否值得添加库依赖项,只是为了一种可以用5-10行代码实现自己的方法。ArrayUtils


它更好(即更简单...在许多情况下,更有效的2)使用类而不是数组。这将负责(至少)增加后备存储。还有一些操作可以负责在列表中的任意位置插入和删除元素。List

例如,该类使用数组作为后备,并根据需要自动增大数组。它不会自动减小支持数组的大小,但您可以告诉它使用该方法执行此操作;例如:ArrayListtrimToSize()

ArrayList l = ...
l.remove(21);
l.trimToSize();  // Only do this if you really have to.

1 - 但请注意,显式 if (a[e] == null) 检查本身很可能是“free”的,因为它们可以与取消引用 a[e] 的值时发生的隐式 null 检查相结合。

2 - 我说它“在许多情况下更有效”,因为ArrayList在需要扩展支持数组时使用简单的“大小加倍”策略。这意味着,如果通过重复追加列表来增加列表,则每个元素平均将额外复制一次。相比之下,如果你对一个数组这样做,你最终会平均复制每个数组元素接近N/2次。


答案 2

您无法调整数组本身的大小,但可以创建一个新数组,并使用一些实用程序函数有效地将元素从旧数组复制到新数组,如下所示:

public static int[] removeElement(int[] original, int element){
    int[] n = new int[original.length - 1];
    System.arraycopy(original, 0, n, 0, element );
    System.arraycopy(original, element+1, n, element, original.length - element-1);
    return n;
}

但是,更好的方法是使用 ArrayList(或类似的列表结构)来存储数据,然后根据需要使用其方法删除元素。