从数组中删除项目并收缩数组
如何从数组中删除项目,然后将数组大小调整为较小的大小? 同样,如果我需要添加其他项目,如何增加容量?
How can I delete an item from an array, and then resize the array to the smaller size?
Likewise, how can I increase the capacity if I need to add another item?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
Java 数组的大小在分配时是固定的,并且无法更改。
如果你想“增长”或“缩小”现有数组,你必须分配一个适当大小的新数组并复制数组元素;例如使用 System.arraycopy(...) 或 Arrays.copyOf(...) 。复制循环也可以工作,尽管它看起来有点笨重...... IMO。
如果你想从数组中“删除”一个或多个项目(真正意义上的......不仅仅是用
null
替换它们),你需要分配一个新的较小的数组并复制跨您想要保留的元素。最后,您可以通过向引用类型数组中的元素分配
null
来“删除”该元素。但这引入了新问题:null
元素来表示某些内容,则无法执行此操作。null
元素的可能性。更加复杂并且存在潜在错误1。有第 3 方库形式的替代方案(例如 Apache Commons
ArrayUtils
),但您可能需要考虑是否值得仅添加一个库依赖项您可以使用 5-10 行代码自行实现的方法。使用
List
类而不是数组更好(即更简单......并且在许多情况下更高效2)。这将(至少)解决后备存储的增长问题。还有一些操作负责在列表中的任何位置插入和删除元素。例如,ArrayList 类使用数组作为支持,并根据需要自动增长数组。它不会自动减小后备数组的大小,但您可以使用
trimToSize()
方法告诉它这样做;例如1 - 但请注意,显式
if (a[e] == null)
检查本身可能是“免费的”,因为它们可以与隐式null 结合使用
检查当您取消引用a[e]
的值时会发生这种情况。2 - 我说它“在许多情况下更有效”,因为
ArrayList当需要增长后备数组时,
使用简单的“双倍大小”策略。这意味着,如果通过重复追加来增长列表,则每个元素平均会被额外复制一次。相比之下,如果您对数组执行此操作,您最终会平均复制每个数组元素接近 N/2 次。The size of a Java array is fixed when you allocate it, and cannot be changed.
If you want to "grow" or "shrink" an existing array, you have to allocate a new array of the appropriate size and copy the array elements; e.g. using
System.arraycopy(...)
orArrays.copyOf(...)
. A copy loop works as well, though it looks a bit clunky ... IMO.If you want to "delete" an item or items from an array (in the true sense ... not just replacing them with
null
), you need to allocate a new smaller array and copy across the elements you want to retain.Finally, you can "erase" an element in an array of a reference type by assigning
null
to it. But this introduces new problems:null
elements to mean something, you can't do this.null
element in the appropriate fashion. More complexity and potential for bugs1.There are alternatives in the form of 3rd-party libraries (e.g. Apache Commons
ArrayUtils
), but you may want to consider whether it is worth adding a library dependency just for the sake of a method that you could implement yourself with 5-10 lines of code.It is better (i.e. simpler ... and in many cases, more efficient2) to use a
List
class instead of an array. This will take care of (at least) growing the backing storage. And there are operations that take care of inserting and deleting elements anywhere in the list.For instance, the
ArrayList
class uses an array as backing, and automatically grows the array as required. It does not automatically reduce the size of the backing array, but you can tell it to do this using thetrimToSize()
method; e.g.1 - But note that the explicit
if (a[e] == null)
checks themselves are likely to be "free", since they can be combined with the implicitnull
check that happens when you dereference the value ofa[e]
.2 - I say it is "more efficient in many cases" because
ArrayList
uses a simple "double the size" strategy when it needs to grow the backing array. This means that if grow the list by repeatedly appending to it, each element will be copied on average one extra time. By contrast, if you did this with an array you would end up copying each array element close to N/2 times on average.您本身无法调整数组的大小,但可以创建一个新数组,并使用一些实用函数将元素从旧数组有效复制到新数组,如下所示:
但是,更好的方法是使用 ArrayList (或类似的列表结构)来存储数据,然后使用其方法根据需要删除元素。
You can't resize the array, per se, but you can create a new array and efficiently copy the elements from the old array to the new array using some utility function like this:
A better approach, however, would be to use an ArrayList (or similar List structure) to store your data and then use its methods to remove elements as needed.
使用 org.apache.commons.lang 中的 ArrayUtils.removeElement(Object[],Object) 是迄今为止最简单的方法。
Using
ArrayUtils.removeElement(Object[],Object)
from org.apache.commons.lang is by far the easiest way to do this.由于数组具有在创建时分配的固定大小,因此您唯一的选择是创建一个不包含要删除的元素的新数组。
如果要删除的元素是最后一个数组项,则可以使用 Arrays.copy 轻松实现:
运行上述代码后,a 现在将指向一个仅包含 1、2 的新数组。
否则,如果要删除的元素不是最后一个元素,则需要创建一个大小为 1 的新数组,并将除要删除的元素之外的所有项目复制到其中。
上面的方法效率不高。如果您需要管理内存中的可变项目列表,最好使用列表。具体来说,
LinkedList
将从列表中删除一个项目,时间复杂度为O(1)
(理论上最快)。Since an array has a fixed size that is allocated when created, your only option is to create a new array without the element you want to remove.
If the element you want to remove is the last array item, this becomes easy to implement using
Arrays.copy
:After running the above code, a will now point to a new array containing only 1, 2.
Otherwise if the element you want to delete is not the last one, you need to create a new array at size-1 and copy all the items to it except the one you want to delete.
The approach above is not efficient. If you need to manage a mutable list of items in memory, better use a List. Specifically
LinkedList
will remove an item from the list inO(1)
(fastest theoretically possible).数组的大小是固定的,创建后无法调整它们的大小。您可以通过将现有项目设置为
null
来删除它:但是您将无法从数组中删除整个槽并将其大小减少 1。
如果您需要动态大小的数组,您可以使用
ArrayList
。有了它,您可以add()
和remove()
对象,它会根据需要增大和缩小。Arrays are fixed in size, you cannot resize them after creating them. You can remove an existing item by setting it to
null
:But you won't be able to delete that entire slot off the array and reduce its size by 1.
If you need a dynamically-sized array, you can use an
ArrayList
. With it, you canadd()
andremove()
objects, and it will grow and shrink as needed.创建数组后无法缩小其大小,但可以将内容复制到另一个较小大小的数组。
There is no way to downsize an array after it is created, but you can copy the contents to another array of a lesser size.
我已经创建了这个函数或类。我有点新,但我的朋友也需要这个,所以我创建了这个:
因为它非常相关,我想我会把它发布在这里。
I have created this function, or class. Im kinda new but my friend needed this also so I created this:
Since its pretty revelant, I thought I would post it here.
如果不使用 System.arraycopy 方法,您可以使用以下命令从数组中删除元素,
其中 3 是您要删除的值。
without using the System.arraycopy method you can delete an element from an array with the following
where 3 is the value you want to remove.
不使用任何预定义函数同样高效:--->>
No use of any pre defined function as well as efficient: --- >>