我们都知道你不能这样做:
for (Object i : l) {
if (condition(i)) {
l.remove(i);
}
}
Run Code Online (Sandbox Code Playgroud)
ConcurrentModificationException等等......这显然有时起作用,但并非总是如此.这是一些特定的代码:
public static void main(String[] args) {
Collection<Integer> l = new ArrayList<>();
for (int i = 0; i < 10; ++i) {
l.add(4);
l.add(5);
l.add(6);
}
for (int i : l) {
if (i == 5) {
l.remove(i);
}
}
System.out.println(l);
}
Run Code Online (Sandbox Code Playgroud)
当然,这会导致:
Exception in thread "main" java.util.ConcurrentModificationException
Run Code Online (Sandbox Code Playgroud)
...即使多线程没有这样做......无论如何.
什么是这个问题的最佳解决方案?如何在循环中从集合中删除项而不抛出此异常?
我也在Collection这里使用任意,不一定是ArrayList,所以你不能依赖get.
AFAIK有两种方法:
例如,
List<Foo> fooListCopy = new ArrayList<Foo>(fooList);
for(Foo foo : fooListCopy){
// modify actual fooList
}
Run Code Online (Sandbox Code Playgroud)
和
Iterator<Foo> itr = fooList.iterator();
while(itr.hasNext()){
// modify actual fooList using itr.remove()
}
Run Code Online (Sandbox Code Playgroud)
是否有任何理由偏好一种方法而不是另一种方法(例如,由于可读性的简单原因,更喜欢第一种方法)?
for (String fruit : list)
{
if("banane".equals(fruit))
list.remove(fruit);
System.out.println(fruit);
}
Run Code Online (Sandbox Code Playgroud)
这里有一个带删除指令的循环.在执行时,我在控制台输出下面得到一些ConcurrentModificationException:
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.AbstractList$Itr.checkForComodification(AbstractList.java:449)
at java.util.AbstractList$Itr.next(AbstractList.java:420)
at Boucle.main(Boucle.java:14)
abricot
banane
Run Code Online (Sandbox Code Playgroud)
问题:如何用循环删除一些元素?
使用迭代器迭代ArrayList时从ArrayList中删除多个项是否安全?
Iterator<String> iterator = nameList.iterator();
while(iterator.hasNext()){
String s = iterator.next();
List<String> list = work(s);
for (String s1 : list) {
nameList.remove(s1);
}
}
Run Code Online (Sandbox Code Playgroud)
该work()方法返回在while循环的运行时期间应从nameList中删除的名称列表.
我知道,当
java.lang.Object
-> java.util.concurrent.CopyOnWriteArrayList<E>
Run Code Online (Sandbox Code Playgroud)
和
java.lang.Object
-> java.util.AbstractCollection<E>
-> java.util.AbstractList<E>
-> java.util.ArrayList<E>
Run Code Online (Sandbox Code Playgroud)
但是我想要的是将的行为添加CopyOnWriteArrayList到ArrayList。
例如:
我想做以下事情。但是tstArry是一个ArrayList。不是CopyOnWriteArrayList
for(TestCls testCls : tstArry)
if(testCls.getVal1().equals("a1"))
tstArry.remove(testCls);
Run Code Online (Sandbox Code Playgroud)
还是这是完成工作的唯一方法?
for(int i = 0; i < tstArry.size(); i++)
if(tstArry.get(i).getVal1().equals("a1"))
tstArry.remove(i--);
Run Code Online (Sandbox Code Playgroud)
tstArry是我没有控件的类中的ArrayList。因此,请把ArrayList的类型更改为另一种是最有效的解决方案。
在我的代码中:
Collection<String> c = new ArrayList<>();
Iterator<String> it = c.iterator();
c.add("Hello");
System.out.println(it.next());
Run Code Online (Sandbox Code Playgroud)
发生异常,因为我的集合在创建迭代器后发生了变化.
但是在这段代码中呢:
ArrayList<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(2);
list.add(3);
for (Integer integer : list) { // Exception is here
if (integer.equals(2)) {
list.remove(integer);
}
}
Run Code Online (Sandbox Code Playgroud)
为什么发生例外?
在第二个代码中,我在for-each循环之前对我的集合进行了更改.