是否有任何快速(和漂亮的)方式从Java中删除数组中的元素?
你可以使用commons lang的ArrayUtils.
array = ArrayUtils.removeElement(array, element)
commons.apache.org库:Javadocs
你的问题不是很清楚.从你自己的答案,我可以更好地告诉你你想做什么:
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); }
注意:这是未经测试的.错误检查留给读者一个练习(如果输入或deleteMe为null,我会抛出IllegalArgumentException;空列表输入上的空列表没有意义.从数组中删除空字符串可能有意义,但我'将它留作练习;当前,如果deleteMe为null,它会在尝试在deleteMe上调用equals时抛出NPE.)
我在这里做的选择:
我使用了LinkedList.迭代应该同样快,如果最终删除大量元素,则可以避免任何调整大小,或者分配太大的列表.您可以使用ArrayList,并将初始大小设置为输入的长度.它可能不会产生太大的影响.
最好的选择是使用集合,但如果由于某种原因出现,请使用arraycopy
.您可以使用它以稍微不同的偏移量从同一个数组复制到同一个数组.
例如:
public void removeElement(Object[] arr, int removedIdx) { System.arraycopy(arr, removedIdx + 1, arr, removedIdx, arr.length - 1 - removedIdx); }
编辑以回应评论(tl; dr):
这不是另一种好方法,它实际上是唯一可接受的方式 - 任何允许此功能的工具(如Java.ArrayList或apache utils)都将使用此方法.此外,你真的应该使用ArrayList(或链接列表,如果你从中间删除很多)所以这甚至不应该是一个问题,除非你做它作为家庭作业.
要分配一个集合(创建一个新数组),然后删除一个元素(该集合将使用arraycopy执行)然后在其上调用toArray(创建一个新的数组),每次删除都会让我们达到一个不是优化问题的地步,这是一个犯罪错误的编程.
假设你有一个数组,比如100mb的ram.现在你想迭代它并删除20个元素.
试试看...
我知道你认为它不会那么大,或者如果你一次删除那么多,你会以不同的方式编码,但是我已经修复了很多代码,其中有人做出了类似的假设.
您无法从基本Java数组中删除元素.请看一下各种Collections和ArrayList.
好看的解决方案是首先使用List而不是数组.
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
.)
我认为问题是在没有使用Collections API的情况下要求解决方案.一个人使用数组来表示低级细节,性能很重要,或者用于松散耦合的SOA集成.在后面,可以将它们转换为Collections并将它们传递给业务逻辑.
对于低级性能的东西,它通常已经被for循环等的快速和肮脏的命令状态混合所模糊.在这种情况下,在集合和数组之间来回转换是麻烦的,不可读的,甚至是资源密集型的.
顺便说一下,TopCoder,有人吗?总是那些数组参数!因此,准备好在竞技场中处理它们.
以下是我对问题的解释和解决方案.它与Bill K和jelovirt给出的功能不同.此外,它可以优雅地处理元素不在数组中的情况.
希望有所帮助!
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; }