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

时间:2020-03-06 14:31:04  来源:igfitidea点击:

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

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

如何删除/删除数组中所有等于" a"的字符串/对象?

解决方案

用Arrays.asList()在数组外制作一个List,然后在所有适当的元素上调用remove()。然后在"列表"上调用" toArray()",再次返回数组。

性能不是很出色,但是如果将其正确封装,则以后总是可以更快地执行某些操作。

将null分配给数组位置。

[如果需要一些现成的代码,请滚动到我的" Edit3"(剪切后)。其余的供后代使用。]

充实Dustman的想法:

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

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

Edit2:以上方法保留了相同的数组(因此数组的长度仍然相同);最后一个元素之后的元素设置为null。如果我们希望新阵列的大小完全符合要求,请改用以下方法:

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

Edit3:如果我们经常在同一课程中使用此代码,则不妨考虑将其添加到课程中:

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

然后该函数变为:

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

然后,这将停止用无用的空字符串数组乱堆堆,否则,每次调用函数时,这些空字符串数组都将被"新"填充。

愤世嫉俗的人的建议(请参阅评论)也将有助于解决乱扔垃圾的问题,为公平起见,我应该提一下:

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

我更喜欢我的方法,因为更容易弄错显式的大小(例如,在错误的列表上调用size())。

关于使它成为列表然后删除然后返回到数组的事情使我感到震惊。尚未测试,但我认为以下方法会更好。是的,我可能没有适当地进行预优化。

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

抱歉,我无法正确显示代码。抱歉,我知道了。再次抱歉,我认为我没有正确阅读问题。

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

编辑:

数组中带有空值的点已被清除。对不起,我的评论。

原版的:

嗯...那条线

array = list.toArray(array);

用null替换数组中已删除元素的所有间隙。这可能很危险,因为删除了元素,但是数组的长度保持不变!

如果要避免这种情况,请使用新的Array作为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));

给出:

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

克里斯·耶斯特·杨(Chris Yester Young)当前接受的答案如下:

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

与代码

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

没有留下任何空值。

我们可以随时执行以下操作:

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

这取决于我们所说的"删除"是什么意思?数组是固定大小的构造,我们无法更改其中的元素数量。因此,我们可以a)创建一个新的,较短的,不包含不需要元素的数组,或者b)将不需要的条目分配给表示其"空"状态的东西;如果我们不使用基元,则通常为null。

在第一种情况下,从数组创建一个列表,删除元素,然后从列表创建一个新的数组。如果性能很重要,请在数组上进行迭代,将不应删除的所有元素分配到列表中,然后从列表中创建一个新数组。在第二种情况下,只需遍历并将null分配给数组条目。