loop on list with remove
1 2 3 4 5 6
| for (String fruit : list )
{
if("banane". equals(fruit ))
list. remove(fruit );
System. out. println(fruit );
} |
这里是一个带有删除指令的循环。在执行时,我在控制台输出下面得到一些ConcurrentModificationException:
问题:如何用循环移除某些元素?
您需要直接使用迭代器,并通过该迭代器删除该项。
1 2 3 4 5 6 7
| for (Iterator <String > iterator = list. iterator(); iterator. hasNext(); ) {
String fruit = iterator. next();
if ("banane". equals(fruit )) {
iterator. remove();
}
System. out. println(fruit );
} |
- 对于一个会认识自己的人来说:不要用增量index和list.size()!!我想用foreach循环更改代码,但它不是正确的soluce。你的就是那个。
- 把it.hasNext()改成iterator.hasNext()就好了!(明显…但谁知道…)
这看起来有点复杂,为什么不做一个正常的for循环呢?我认为它看起来更干净,不会抛出这个错误。如果你把什么东西拿走,我就谴责你。不管怎样,至少我的工作。我想,这种自动循环更多的是为了方便编码,所以如果它们不方便,就不要使用它们。
1 2 3 4 5 6 7 8
| for (int i = list. size() - 1; i >=0; i --) {
String fruit = list. get(i );
System. out. println(fruit );
if ("banane". equals(fruit )) {
list. remove(fruit );
}
} |
- 在一个大的列表中,这将非常缓慢(算法术语中的O(n^2),因为List#remove(Object)需要通过对给定对象的列表执行线性搜索来重新工作。如果可能的话,最好使用索引,这将使它在1(11)次。
除了直接使用Iterator(我建议)之外,您还可以将要删除的元素存储在其他列表中。
1 2 3 4 5 6 7 8 9
| List <String > toRemove = new ArrayList <String >();
for (String fruit : list ) {
if ("banane". equals(fruit ))
toRemove. add(fruit );
System. out. println(fruit );
}
for (String fruit : toRemove ) {
list. remove(fruit );
} |
注意,我不推荐这个,这只是一个选择。:)
- 你的解决方案太冗长了
- 是的,是的。这就是为什么我会使用基于iterator的解决方案——这就是我所写的。
- 有多种方法可以做到这一点,但大多数方法都是错误的;)
- "错误"的含义不止一个。
1 2 3 4 5 6 7
| for(Iterator <String > iter = list. iterator(); iter. hasNext(); )
{
String fruit = iter. next();
if("banana". equals(fruit ))
iter. remove();
System. out. println(fruit );
} |
使用for循环,并按相反顺序循环集合。(也就是说,从最后一个元素开始,循环到第一个元素。这样做,就不会因为从集合中删除元素而被更改的索引带来问题。
您在发布的示例中得到异常,因为迭代器迭代的列表已经更改,这意味着迭代器将变为无效的。
- 听起来很危险。如果内存不是连续的,那么双链接列表等如何?我不知道列表中是否有Java中的EDOCX1 2,或者EDOCX1 3如何实现,但是如果它像C++一样,如果你的方法与EDCOX1,4,ED无关,我会感到惊讶。
1 2 3 4 5 6 7 8 9
| ArrayList <String > list = new ArrayList <String >(Arrays. asList("a", "b", "c", "d"));
Iterator <String > iter = list. iterator();
while (iter. hasNext()) {
String s = iter. next();
if (s. equals("a")) {
iter. remove();
}
} |
是最好的方法。
类似于bombe的建议,但是通过迭代列表副本减少了代码行,但是从原始列表中删除了代码行;
1 2 3 4 5 6 7
| List <String > temp = new ArrayList <String >(list );
for (String fruit : temp )
{
if("banane". equals(fruit ))
list. remove(fruit );
System. out. println(fruit );
} |
我个人认为这比用迭代器迭代更好。
- 我觉得它更容易阅读
- 我想说这很容易出问题。有两个不需要第二个的列表。就我两分钱。
- @Cheekoo,我可以看到它如何使用不必要的内存,但是我看不到一个有能力的开发人员如何使用这个方法引入bug。
- 哈哈!我同意。但是现在您已经开始使用条件语句了!"有能力的开发商";)
- 这有不必要的迭代。new ArrayList(list)将迭代list。然后用for循环再次迭代它。
- @史蒂夫郭,真的