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

发布于 2024-10-15 13:24:03 字数 57 浏览 1 评论 0原文

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

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

饭团 2024-10-22 13:24:03

Java 数组的大小在分配时是固定的,并且无法更改。

  • 如果你想“增长”或“缩小”现有数组,你必须分配一个适当大小的新数组并复制数组元素;例如使用 System.arraycopy(...) 或 Arrays.copyOf(...) 。复制循环也可以工作,尽管它看起来有点笨重...... IMO。

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

  • 最后,您可以通过向引用类型数组中的元素分配 null 来“删除”该元素。但这引入了新问题:

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

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


使用 List 类而不是数组更好(即更简单......并且在许多情况下更高效2)。这将(至少)解决后备存储的增长问题。还有一些操作负责在列表中的任何位置插入和删除元素。

例如,ArrayList 类使用数组作为支持,并根据需要自动增长数组。它不会自动减小后备数组的大小,但您可以使用 trimToSize() 方法告诉它这样做;例如

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

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(...) or Arrays.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:

    • If you were using null elements to mean something, you can't do this.
    • All of the code that uses the array now has to deal with the possibility of a 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 the trimToSize() method; e.g.

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

1 - But note that the explicit if (a[e] == null) checks themselves are likely to be "free", since they can be combined with the implicit null check that happens when you dereference the value of a[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.

踏雪无痕 2024-10-22 13:24:03

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

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 (或类似的列表结构)来存储数据,然后使用其方法根据需要删除元素。

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:

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;
}

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.

蓝眼睛不忧郁 2024-10-22 13:24:03

使用 org.apache.commons.lang 中的 ArrayUtils.removeElement(Object[],Object) 是迄今为止最简单的方法。

int[] numbers = {1,2,3,4,5,6,7};
//removing number 1
numbers =(int[])ArrayUtils.removeElement(numbers, 1);

Using ArrayUtils.removeElement(Object[],Object) from org.apache.commons.lang is by far the easiest way to do this.

int[] numbers = {1,2,3,4,5,6,7};
//removing number 1
numbers =(int[])ArrayUtils.removeElement(numbers, 1);
不交电费瞎发啥光 2024-10-22 13:24:03

由于数组具有在创建时分配的固定大小,因此您唯一的选择是创建一个不包含要删除的元素的新数组。

如果要删除的元素是最后一个数组项,则可以使用 Arrays.copy 轻松实现:

int a[] = { 1, 2, 3};
a = Arrays.copyOf(a, 2);

运行上述代码后,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:

int a[] = { 1, 2, 3};
a = Arrays.copyOf(a, 2);

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 in O(1) (fastest theoretically possible).

如梦亦如幻 2024-10-22 13:24:03

数组的大小是固定的,创建后无法调整它们的大小。您可以通过将现有项目设置为 null 来删除它:

objects[4] = 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:

objects[4] = 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 can add() and remove() objects, and it will grow and shrink as needed.

药祭#氼 2024-10-22 13:24:03
object[] newarray = new object[oldarray.Length-1];

for(int x=0; x < array.Length; x++)
{
  if(!(array[x] == value_of_array_to_delete))
  // if(!(x == array_index_to_delete))
   {
     newarray[x] = oldarray[x];
   }
}

创建数组后无法缩小其大小,但可以将内容复制到另一个较小大小的数组。

object[] newarray = new object[oldarray.Length-1];

for(int x=0; x < array.Length; x++)
{
  if(!(array[x] == value_of_array_to_delete))
  // if(!(x == array_index_to_delete))
   {
     newarray[x] = oldarray[x];
   }
}

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.

雅心素梦 2024-10-22 13:24:03

我已经创建了这个函数或类。我有点新,但我的朋友也需要这个,所以我创建了这个:

public String[] name(int index, String[] z ){
    if(index > z.length){
        return z;
    } else {
        String[] returnThis = new String[z.length - 1];
        int newIndex = 0;
        for(int i = 0; i < z.length; i++){
            if(i != index){
                returnThis[newIndex] = z[i];
                newIndex++;
            }
        }
        return returnThis; 
    }
}

因为它非常相关,我想我会把它发布在这里。

I have created this function, or class. Im kinda new but my friend needed this also so I created this:

public String[] name(int index, String[] z ){
    if(index > z.length){
        return z;
    } else {
        String[] returnThis = new String[z.length - 1];
        int newIndex = 0;
        for(int i = 0; i < z.length; i++){
            if(i != index){
                returnThis[newIndex] = z[i];
                newIndex++;
            }
        }
        return returnThis; 
    }
}

Since its pretty revelant, I thought I would post it here.

瑶笙 2024-10-22 13:24:03

如果不使用 System.arraycopy 方法,您可以使用以下命令从数组中删除元素,

    int i = 0;
    int x = 0;
    while(i < oldArray.length){
        if(oldArray[i] == 3)i++;

        intArray[x] = oldArray[i];
        i++;
        x++;
    }

其中 3 是您要删除的值。

without using the System.arraycopy method you can delete an element from an array with the following

    int i = 0;
    int x = 0;
    while(i < oldArray.length){
        if(oldArray[i] == 3)i++;

        intArray[x] = oldArray[i];
        i++;
        x++;
    }

where 3 is the value you want to remove.

夏天碎花小短裙 2024-10-22 13:24:03

不使用任何预定义函数同样高效:--->>

public static void Delete(int d , int[] array )
{       
    Scanner in = new Scanner (System.in);

    int i , size = array.length;

    System.out.println("ENTER THE VALUE TO DELETE? ");

     d = in.nextInt();

        for ( i=0;i< size;i++)
        {
                if (array[i] == d)
                        {


                            int[] arr3 =new int[size-1];
                            int[] arr4 = new int[i];
                            int[] arr5 = new int[size-i-1];

                                    for (int a =0 ;a<i;a++)
                                    {
                                        arr4[a]=array[a];
                                        arr3[a] = arr4[a];
                                    }
                                     for (int a =i ;a<size-1;a++)
                                     {
                                         arr5[a-i] = array[a+1];
                                         arr3[a] = arr5[a-i];

                                     }


                System.out.println(Arrays.toString(arr3));

                        }
                else System.out.println("************");    


        }

}

No use of any pre defined function as well as efficient: --- >>

public static void Delete(int d , int[] array )
{       
    Scanner in = new Scanner (System.in);

    int i , size = array.length;

    System.out.println("ENTER THE VALUE TO DELETE? ");

     d = in.nextInt();

        for ( i=0;i< size;i++)
        {
                if (array[i] == d)
                        {


                            int[] arr3 =new int[size-1];
                            int[] arr4 = new int[i];
                            int[] arr5 = new int[size-i-1];

                                    for (int a =0 ;a<i;a++)
                                    {
                                        arr4[a]=array[a];
                                        arr3[a] = arr4[a];
                                    }
                                     for (int a =i ;a<size-1;a++)
                                     {
                                         arr5[a-i] = array[a+1];
                                         arr3[a] = arr5[a-i];

                                     }


                System.out.println(Arrays.toString(arr3));

                        }
                else System.out.println("************");    


        }

}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文