从 Array 中删除元素(Java)

有没有什么快速(而且漂亮)的方法可以从 Java 的数组中删除元素?

980217 次浏览

不能从基本的 Java 数组中删除元素。请查看各种集合和数组列表。

当然,创建另一个数组:)

好看的解决方案是首先使用 List 而不是 array。

List.remove(index)

如果 使用数组,那么对 System.arraycopy的两次调用很可能是最快的。

Foo[] result = new Foo[source.length - 1];
System.arraycopy(source, 0, result, 0, index);
if (source.length != index) {
System.arraycopy(source, index + 1, result, index, source.length - index - 1);
}

(Arrays.asList也是使用数组的一个很好的候选者,但它似乎不支持 remove。)

使用 ArrayList:

alist.remove(1); //removes the element at position 1

我希望您使用 java 集合/java commons 集合!

使用 java.util. ArrayList,您可以执行以下操作:

yourArrayList.remove(someObject);


yourArrayList.add(someObject);

如果不感兴趣调整数组的大小,则将要移除的项与最后一个项交换。

好的,非常感谢 现在我用这样的东西:

public static String[] removeElements(String[] input, String deleteMe) {
if (input != null) {
List<String> list = new ArrayList<String>(Arrays.asList(input));
for (int i = 0; i < list.size(); i++) {
if (list.get(i).equals(deleteMe)) {
list.remove(i);
}
}
return list.toArray(new String[0]);
} else {
return new String[0];
}
}

您可以使用 commons lang 的 ArrayUtils。

array = ArrayUtils.removeElement(array, element)

Commons.apache.org 库: Javadocs

最好的选择是使用一个集合,但是如果由于某种原因不能使用它,则使用 arraycopy。您可以使用它以稍微不同的偏移量从同一个数组复制或复制到同一个数组。

例如:

public void removeElement(Object[] arr, int removedIdx) {
System.arraycopy(arr, removedIdx + 1, arr, removedIdx, arr.length - 1 - removedIdx);
}

根据评论进行编辑:

这不是另一种好的方式,它是唯一可以接受的方式——任何允许这种功能的工具(比如 Java)。ArrayList 或 apache utils)将秘密地使用这个方法。此外,你真的应该使用数组列表(或链表,如果你从中间删除了很多) ,所以这应该不是一个问题,除非你正在做它作为家庭作业。

为了分配一个集合(创建一个新数组) ,然后删除一个元素(这个集合将使用数组拷贝来完成) ,然后对它调用 toArray (创建一个 SECOND 新数组) ,因为每次删除都会让我们发现这不是一个优化问题,而是一个非常糟糕的编程问题。

假设你有一个占用100mb 内存的数组。现在需要对它进行迭代并删除20个元素。

试试看..。

我知道你认为它不会那么大,或者如果你一次删除那么多,你会编写不同的代码,但是我已经修复了大量的代码,其中有人做出了这样的假设。

你的问题不是很清楚。从你自己的回答中,我可以更清楚地看出你想做什么:

public static String[] removeElements(String[] input, String deleteMe) {
List result = new LinkedList();


for(String item : input)
if(!deleteMe.equals(item))
result.add(item);


return result.toArray(input);
}

注意: 这是未经测试的。错误检查留给读者作为练习(如果 inputdeleteMe为空,我将抛出 IllegalArgumentException; 空列表输入上的空列表没有意义。从数组中删除 null String 可能是有意义的,但是我将把它留作练习; 当前,如果 deleteMe为 null,那么当它尝试在 deleteMe上调用 equals 时,它将抛出一个 NPE。)

我在这里做出的选择:

我用的是 LinkedList。迭代应该同样快,并且您可以避免任何调整大小,或者如果您最终删除了大量元素,就可以避免分配过大的列表。您可以使用 ArrayList,并将初始大小设置为输入的长度。这可能不会有太大的区别。

您可以使用 ArrayUtils API以一种“漂亮的方式”移除它。它在 Array 上实现了许多操作(删除、查找、添加、包含等)。
看看吧,这让我的生活更简单了。

我认为问题是要求解决 没有集合 API 的使用问题。人们可以使用数组来处理低层次的细节问题(性能很重要) ,也可以使用数组来进行松散耦合的 SOA 集成。在后一种情况下,可以将它们转换为 Collective 并将它们作为集合传递给业务逻辑。

对于低级别的性能部分,通常已经被 For 循环等快速而肮脏的命令式状态混合模糊了。在这种情况下,在集合和数组之间来回转换是非常麻烦的,不可读的,甚至是资源密集型的。

顺便问一下,TopCoder,有人知道吗?总是那些数组参数!所以准备好在竞技场应付他们。

下面是我对这个问题的解释,以及一个解决方案。它的功能不同于 Bill KJelovirt给出的功能。此外,当元素不在数组中时,它会优雅地处理这种情况。

希望能帮上忙!

public char[] remove(char[] symbols, char c)
{
for (int i = 0; i < symbols.length; i++)
{
if (symbols[i] == c)
{
char[] copy = new char[symbols.length-1];
System.arraycopy(symbols, 0, copy, 0, i);
System.arraycopy(symbols, i+1, copy, i, symbols.length-i-1);
return copy;
}
}
return symbols;
}

Bill K 和 dadinn 编写的文章需要更多的前提条件

Object[] newArray = new Object[src.length - 1];
if (i > 0){
System.arraycopy(src, 0, newArray, 0, i);
}


if (newArray.length > i){
System.arraycopy(src, i + 1, newArray, i, newArray.length - i);
}


return newArray;

您不能更改数组的长度,但可以通过复制新值并将其存储到现有索引号来更改索引中的值。 1 = Mike 2 = Jeff//10 = George 11转到1覆盖 Mike。

Object[] array = new Object[10];
int count = -1;


public void myFunction(String string) {
count++;
if(count == array.length) {
count = 0;  // overwrite first
}
array[count] = string;
}