从数组中删除元素(Java)[重复]
Posted
技术标签:
【中文标题】从数组中删除元素(Java)[重复]【英文标题】:Removing an element from an Array (Java) [duplicate] 【发布时间】:2010-10-13 04:13:03 【问题描述】:有没有什么快速(且美观)的方法可以从 Java 中的数组中删除元素?
【问题讨论】:
即使问题是重复的,另一个问题的答案既不快也不好看。它将数组转换为数组列表(手动)。 【参考方案1】:您不能从基本 Java 数组中删除元素。看看各种 Collections 和 ArrayList。
【讨论】:
我知道,我只是想要一个漂亮的方式与 arraylists 或 sth。像这样,有什么提示吗? +1:使用LinkedList,生活更简单。 LinkedList 很少是一个好主意。 List intrrface 为您提供随机访问,但 LinkedList 提供 O(n) 访问时间而不是 O(1)。 例如,您可以通过 System.arrayCopy 从数组中删除元素,但不能更改大小。然而,列表是一个更好的解决方案。 @Tom:LinkedList 是否是正确的选择也取决于其他因素。 “随机访问”,即通过索引访问链表,是O(n)。【参考方案2】:当然,创建另一个数组:)
【讨论】:
【参考方案3】:看起来不错的解决方案是首先使用列表而不是数组。
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
。)
【讨论】:
+1:使用 LinkedList 或 ArrayList。 最终副本应该是if (result.length != index)...
而不是if (source.length != index)...
?【参考方案4】:
使用ArrayList
:
alist.remove(1); //removes the element at position 1
【讨论】:
【参考方案5】:希望你使用 java 集合/java commons 集合!
使用 java.util.ArrayList,您可以执行以下操作:
yourArrayList.remove(someObject);
yourArrayList.add(someObject);
【讨论】:
数组不是集合... 但大多数集合都是数组!见:en.wikipedia.org/wiki/Array 是的,但是这个问题是 java 标记的,并且在 java 中,数组不是集合...... 我不会开始就什么是元素集合什么不是元素的集合展开宗教战争。编写包含大量程序元素的 Java 很糟糕!从 OO 中获利!您几乎可以从 Java Array 构造创建每个集合。 我不明白为什么这家伙被改装了。如果您需要能够轻松地从有序组中删除元素,那么很明显,数组可能是首先使用的错误类型的组。所以 List 是一个很好的建议,而 Set 可能会更好,这取决于应用程序。【参考方案6】:Copy你原来的数组变成了另一个数组,没有元素被删除。
更简单的方法是使用 List、Set... 并使用 remove() 方法。
【讨论】:
【参考方案7】:如果不希望缩小数组的大小,则将要删除的项目与最后一个项目交换。
【讨论】:
如果数组在删除之前排序,这会破坏事情。【参考方案8】:好的,谢谢 现在我用这样的东西:
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];
【讨论】:
如果你真的需要保持初始数组不变,你最好创建一个空列表并用正确的元素填充它,而不是这样做。 我不确定这是人们在建议使用集合时的想法,但无论如何,请小心那些列表索引。看起来您在任何删除后立即跳过该元素(尝试 “a”、“b”、“deleteMe”、“deleteMe”、“c”)。【参考方案9】:您可以使用 commons lang 的 ArrayUtils。
array = ArrayUtils.removeElement(array, element)
commons.apache.org library:Javadocs
【讨论】:
@Clive Guava 似乎只适用于收藏。 这是否也会缩小数组? @SupunWijerathne 必须更改大小/长度。 它在 Java8 中不起作用,我没有得到任何名称为removeElement
的方法
@AtulAgrawal 您需要在最后一行的链接中包含库。【参考方案10】:
最好的选择是使用集合,但如果由于某种原因无法使用,请使用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 个元素。
试一试……
我知道你假设它不会那么大,或者如果你一次删除那么多你会以不同的方式编码,但我已经修复了很多代码,其中有人做出了这样的假设。
【讨论】:
在“删除”之后(即,将数组左移一个元素)不会有结束元素的副本吗?即删除后 a.length 将相同,不是吗?我并不是说我不喜欢这个想法,只是说人们需要意识到这一点。 +1。这适用于我的目的。 (我修复了您在示例中遇到的小问题。希望您不介意。) 是的,这只会将元素向左移动,最后一个元素仍然存在。我们必须使用新数组来复制。 顺便说一句,这也是 org.apache.commons.lang.ArrayUtils 所做的。 假设如果您在数组中添加和删除元素,您也在跟踪数组中的“最后一个”项,因此不需要复制。【参考方案11】:你的问题不是很清楚。从您自己的回答中,我可以更好地说明您要做什么:
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);
注意:这是未经测试的。错误检查留给读者作为练习(如果input
或deleteMe
为空,我会抛出IllegalArgumentException
;空列表输入上的空列表没有意义。从数组中删除空字符串可能有道理,但我也会把它留作练习;目前,如果deleteMe
为空,它会在尝试在deleteMe
上调用equals 时抛出NPE
。)
我在这里做出的选择:
我使用了LinkedList
。迭代应该同样快,并且避免任何调整大小,或在最终删除大量元素时分配太大的列表。您可以使用ArrayList
,并将初始大小设置为输入的长度。这可能不会有太大的不同。
【讨论】:
注意,您需要使用List<String>
结果。当我在当前编译器中执行此操作时,toArray 命令会给出类型错误(另一种解决方案是强制转换结果。)【参考方案12】:
您可以使用ArrayUtils API 以“好看的方式”将其删除。它在数组上实现了许多操作(删除、查找、添加、包含等)。 看一看。它让我的生活变得更简单。
【讨论】:
【参考方案13】:我认为问题是要求不使用 Collections API 的解决方案。一种将数组用于性能很重要的低级别细节,或者用于松散耦合的 SOA 集成。后面就可以把它们转成Collection,照这样传给业务逻辑了。
对于低级性能的东西,它通常已经被 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;
【讨论】:
太棒了。太多回复回答了对 OP 的不同问题。【参考方案14】: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;
【讨论】:
【参考方案15】:您无法更改数组的长度,但您可以通过复制新值并将它们存储到现有索引号来更改索引保存的值。 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;
【讨论】:
我认为指出,数组的长度不能改变是一个重要的细节!以上是关于从数组中删除元素(Java)[重复]的主要内容,如果未能解决你的问题,请参考以下文章