如何从Java中的数组中删除对象?
给定一个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分配给数组条目。