如何从 Java 中的数组中删除对象?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/112503/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 08:24:21  来源:igfitidea点击:

How do I remove objects from an array in Java?

javaarraysdata-structuresdata-manipulation

提问by ramayac

Given an array of nObjects, let's say it is an array of strings, and it has the following values:

给定一个包含n 个对象的数组,假设它是一个字符串数组,它具有以下值:

foo[0] = "a";
foo[1] = "cc";
foo[2] = "a";
foo[3] = "dd";

What do I have to do to delete/remove all the strings/objects equal to "a"in the array?

我该怎么做才能删除/删除数组中等于“a”的所有字符串/对象?

采纳答案by Chris Jester-Young

[If you want some ready-to-use code, please scroll to my "Edit3" (after the cut). The rest is here for posterity.]

[如果你想要一些现成的代码,请滚动到我的“Edit3”(剪切后)。其余的留在这里供后代使用。]

To flesh out Dustman's idea:

为了充实清洁工的想法

List<String> list = new ArrayList<String>(Arrays.asList(array));
list.removeAll(Arrays.asList("a"));
array = list.toArray(array);

Edit: I'm now using Arrays.asListinstead of Collections.singleton: singleton is limited to one entry, whereas the asListapproach allows you to add other strings to filter out later: Arrays.asList("a", "b", "c").

编辑:我现在使用Arrays.asList而不是Collections.singleton: singleton 仅限于一个条目,而该asList方法允许您添加其他字符串以稍后过滤掉:Arrays.asList("a", "b", "c")

Edit2: The above approach retains the same array (so the array is still the same length); the element after the last is set to null. If you want a newarray sized exactly as required, use this instead:

Edit2:上面的方法保留了相同的数组(所以数组仍然是相同的长度);最后一个之后的元素设置为空。如果您想要一个大小完全符合要求的数组,请改用:

array = list.toArray(new String[0]);


Edit3: If you use this code on a frequent basis in the same class, you may wish to consider adding this to your class:

Edit3:如果您在同一个类中经常使用此代码,您可能希望考虑将其添加到您的类中:

private static final String[] EMPTY_STRING_ARRAY = new String[0];

Then the function becomes:

那么函数就变成了:

List<String> list = new ArrayList<>();
Collections.addAll(list, array);
list.removeAll(Arrays.asList("a"));
array = list.toArray(EMPTY_STRING_ARRAY);

This will then stop littering your heap with useless empty string arrays that would otherwise be newed each time your function is called.

然后,这将停止用无用的空字符串数组乱扔堆,否则new每次调用函数时都会对其进行编辑。

cynicalman's suggestion (see comments) will also help with the heap littering, and for fairness I should mention it:

愤世嫉俗的人的建议(见评论)也将有助于堆垃圾,为了公平起见,我应该提到它:

array = list.toArray(new String[list.size()]);

I prefer my approach, because it may be easier to get the explicit size wrong (e.g., calling size()on the wrong list).

我更喜欢我的方法,因为它可能更容易得到错误的显式大小(例如,调用size()错误的列表)。

回答by Dustman

Make a Listout of the array with Arrays.asList(), and call remove()on all the appropriate elements. Then call toArray()on the 'List' to make back into an array again.

使用List, 从数组中取出一个Arrays.asList(),并调用remove()所有适当的元素。然后调用toArray()“列表”以再次返回数组。

Not terribly performant, but if you encapsulate it properly, you can always do something quicker later on.

性能不是很好,但是如果您正确地封装它,您以后总是可以更快地做一些事情。

回答by alfinoba

Assign null to the array locations.

将 null 分配给数组位置。

回答by shsteimer

Something about the make a list of it then remove then back to an array strikes me as wrong. Haven't tested, but I think the following will perform better. Yes I'm probably unduly pre-optimizing.

关于制作它的列表然后删除然后返回到数组的一些事情让我觉得是错误的。还没有测试,但我认为以下会表现得更好。是的,我可能进行了过度的预优化。

boolean [] deleteItem = new boolean[arr.length];
int size=0;
for(int i=0;i<arr.length;i==){
   if(arr[i].equals("a")){
      deleteItem[i]=true;
   }
   else{
      deleteItem[i]=false;
      size++;
   }
}
String[] newArr=new String[size];
int index=0;
for(int i=0;i<arr.length;i++){
   if(!deleteItem[i]){
      newArr[index++]=arr[i];
   }
}

回答by AngelOfCake

Arrgh, I can't get the code to show up correctly. Sorry, I got it working. Sorry again, I don't think I read the question properly.

啊,我无法让代码正确显示。对不起,我让它工作了。再次抱歉,我认为我没有正确阅读问题。

String  foo[] = {"a","cc","a","dd"},
remove = "a";
boolean gaps[] = new boolean[foo.length];
int newlength = 0;

for (int c = 0; c<foo.length; c++)
{
    if (foo[c].equals(remove))
    {
        gaps[c] = true;
        newlength++;
    }
    else 
        gaps[c] = false;

    System.out.println(foo[c]);
}

String newString[] = new String[newlength];

System.out.println("");

for (int c1=0, c2=0; c1<foo.length; c1++)
{
    if (!gaps[c1])
    {
        newString[c2] = foo[c1];
        System.out.println(newString[c2]);
        c2++;
    }
}

回答by GHad

EDIT:

编辑:

The point with the nulls in the array has been cleared. Sorry for my comments.

数组中具有空值的点已被清除。抱歉我的评论。

Original:

原来的:

Ehm... the line

嗯……那条线

array = list.toArray(array);

replaces all gaps in the array where the removed element has been with null. This might be dangerous, because the elements are removed, but the length of the array remains the same!

将数组中已删除元素所在的所有空白替换为null。这可能很危险,因为元素被删除了,但数组的长度保持不变!

If you want to avoid this, use a new Array as parameter for toArray(). If you don`t want to use removeAll, a Set would be an alternative:

如果您想避免这种情况,请使用新数组作为 toArray() 的参数。如果您不想使用 removeAll,则可以使用 Set 替代:

        String[] array = new String[] { "a", "bc" ,"dc" ,"a", "ef" };

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

        Set<String> asSet = new HashSet<String>(Arrays.asList(array));
        asSet.remove("a");
        array = asSet.toArray(new String[] {});

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

Gives:

给出:

[a, bc, dc, a, ef]
[dc, ef, bc]

Where as the current accepted answer from Chris Yester Young outputs:

正如 Chris Yester Young 输出的当前接受的答案:

[a, bc, dc, a, ef]
[bc, dc, ef, null, ef]

with the code

用代码

    String[] array = new String[] { "a", "bc" ,"dc" ,"a", "ef" };

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

    List<String> list = new ArrayList<String>(Arrays.asList(array));
    list.removeAll(Arrays.asList("a"));
    array = list.toArray(array);        

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

without any null values left behind.

没有留下任何空值。

回答by GHad

You can always do:

你总是可以这样做:

int i, j;
for (i = j = 0; j < foo.length; ++j)
  if (!"a".equals(foo[j])) foo[i++] = foo[j];
foo = Arrays.copyOf(foo, i);

回答by DJClayworth

It depends on what you mean by "remove"? An array is a fixed size construct - you can't change the number of elements in it. So you can either a) create a new, shorter, array without the elements you don't want or b) assign the entries you don't want to something that indicates their 'empty' status; usually null if you are not working with primitives.

这取决于您所说的“删除”是什么意思?数组是一个固定大小的结构——你不能改变其中的元素数量。因此,您可以 a) 创建一个新的、更短的数组,而没有您不想要的元素,或者 b) 将您不想要的条目分配给指示其“空”状态的内容;如果您不使用原语,通常为 null。

In the first case create a List from the array, remove the elements, and create a new array from the list. If performance is important iterate over the array assigning any elements that shouldn't be removed to a list, and then create a new array from the list. In the second case simply go through and assign null to the array entries.

在第一种情况下,从数组中创建一个列表,删除元素,然后从列表中创建一个新数组。如果性能很重要,则遍历数组,将不应删除的任何元素分配给列表,然后从列表中创建一个新数组。在第二种情况下,只需通过并将 null 分配给数组条目。

回答by bugs_

You can use external library:

您可以使用外部库:

org.apache.commons.lang.ArrayUtils.remove(java.lang.Object[] array, int index)

It is in project Apache Commons Lang http://commons.apache.org/lang/

它在 Apache Commons Lang 项目中http://commons.apache.org/lang/

回答by DDSports

I realise this is a very old post, but some of the answers here helped me out, so here's my tuppence' ha'penny's worth!

我意识到这是一个很老的帖子,但这里的一些答案帮助了我,所以这是我的 tuppence' ha'penny 的价值!

I struggled getting this to work for quite a while before before twigging that the array that I'm writing back into needed to be resized, unless the changes made to the ArrayListleave the list size unchanged.

我努力让它工作了很长一段时间,然后才知道我正在写回的数组需要调整大小,除非ArrayList对列表所做的更改保持列表大小不变。

If the ArrayListthat you're modifying ends up with greater or fewer elements than it started with, the line List.toArray()will cause an exception, so you need something like List.toArray(new String[] {})or List.toArray(new String[0])in order to create an array with the new (correct) size.

如果ArrayList您正在修改的 结束时的元素比开始时更多或更少,该行将List.toArray()导致异常,因此您需要类似List.toArray(new String[] {})List.toArray(new String[0])以创建具有新(正确)大小的数组。

Sounds obvious now that I know it. Not so obvious to an Android/Java newbie who's getting to grips with new and unfamiliar code constructs and not obvious from some of the earlier posts here, so just wanted to make this point really clear for anybody else scratching their heads for hours like I was!

现在我知道了,这听起来很明显。对于开始处理新的和不熟悉的代码结构的 Android/Java 新手来说并不是那么明显,而且从这里的一些早期帖子中并不明显,所以只想让其他人真正清楚这一点,因为其他人像我一样挠了几个小时!