163

是否有任何快速(且美观)的方法可以从 Java 中的数组中删除元素?

4

15 回答 15

259

您可以使用 commons lang 的 ArrayUtils。

array = ArrayUtils.removeElement(array, element)

commons.apache.org 库:Javadocs

于 2009-03-13T21:40:26.030 回答
47

你的问题不是很清楚。从您自己的回答中,我可以更好地说明您要做什么:

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

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

我在这里做出的选择:

我用了一个LinkedList. 迭代应该同样快,并且避免任何调整大小,或在最终删除大量元素时分配太大的列表。您可以使用ArrayList, 并将初始大小设置为输入的长度。它可能不会有太大的不同。

于 2009-03-13T22:36:41.013 回答
46

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

例如:

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

编辑以回应评论:

这不是另一种好方法,它确实是唯一可接受的方法——任何允许此功能的工具(如 Java.ArrayList 或 apache utils)都将在幕后使用此方法。此外,你真的应该使用 ArrayList (或者如果你从中间删除了很多链接列表)所以这甚至不应该是一个问题,除非你把它作为家庭作业。

要分配一个集合(创建一个新数组),然后删除一个元素(该集合将使用 arraycopy 执行此操作),然后在其上调用 toArray(创建一个 SECOND 新数组),每次删除都会将我们带到不是优化问题的地步,这是非常糟糕的编程。

假设您有一个阵列占用了 100mb 的内存。现在您要遍历它并删除 20 个元素。

试试看...

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

于 2009-03-13T21:55:20.333 回答
40

您不能从基本 Java 数组中删除元素。请查看各种 Collections 和 ArrayList。

于 2009-03-13T14:13:57.523 回答
16

看起来不错的解决方案是首先使用列表而不是数组。

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

于 2009-03-13T14:15:29.640 回答
13

我认为问题是在不使用 Collections API 的情况下寻求解决方案。一种将数组用于性能很重要的低级别细节,或者用于松散耦合的 SOA 集成。在后面,可以将它们转换为 Collections 并将它们传递给业务逻辑。

对于低级性能的东西,它通常已经被 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;
}
于 2010-08-13T12:40:17.547 回答
4

您可以使用ArrayUtils API以“美观的方式”将其删除。它在数组上实现了许多操作(删除、查找、添加、包含等)。
看一看。它让我的生活变得更简单。

于 2009-03-14T17:33:30.400 回答
3

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

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];
    }
}
于 2009-03-13T14:44:34.813 回答
3

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;
于 2010-09-09T09:31:57.173 回答
3

您不能更改数组的长度,但您可以通过复制新值并将它们存储到现有索引号来更改索引保存的值。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;    
}
于 2012-10-28T18:17:55.800 回答
0

我希望你使用java collection/java commons collections!

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

yourArrayList.remove(someObject);

yourArrayList.add(someObject);
于 2009-03-13T14:16:02.840 回答
0

原始数组复制到另一个数组中,而不删除要删除的元素。

一种更简单的方法是使用 List、Set... 并使用 remove() 方法。

于 2009-03-13T14:17:25.707 回答
0

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

于 2009-03-13T14:26:01.660 回答
-4

使用ArrayList

alist.remove(1); //removes the element at position 1
于 2009-03-13T14:15:37.753 回答
-6

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

于 2009-03-13T14:14:52.640 回答