hak*_*ata 19 java foreach for-loop arraylist
我正在尝试使用arraylist的foreach循环,但是当我使用它时,它会给我错误,但是当我使用普通for循环时,它完美地工作,可能是什么问题?
代码在这里:
for (Pair p2 : R) {
if ((p2.getFirstElm() == p.getSecondElm()) && (p2.getFirstElm() != p2.getSecondElm()))
R.add(new Pair (p.getFirstElm(), p2.getSecondElm()));
else if ((p2.getSecondElm() == p.getFirstElm()) && (p2.getFirstElm() != p2.getSecondElm()))
R.add(new Pair (p2.getFirstElm(), p.getSecondElm()));
// else
// There are no transitive pairs in R.
}
Run Code Online (Sandbox Code Playgroud)
这是不起作用的循环,这是一个有效的循环:
for (int i = 0; i < R.size(); i++) {
if ((R.get(i).getFirstElm() == p.getSecondElm()) && (R.get(i).getFirstElm() != R.get(i).getSecondElm()))
R.add(new Pair (p.getFirstElm(), R.get(i).getSecondElm()));
else if ((R.get(i).getSecondElm() == p.getFirstElm()) && (R.get(i).getFirstElm() != R.get(i).getSecondElm()))
R.add(new Pair (R.get(i).getFirstElm(), p.getSecondElm()));
//else
// There are no transitive pairs in R.
}
Run Code Online (Sandbox Code Playgroud)
我在使用foreach循环时遇到的错误是:
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.AbstractList$Itr.checkForComodification(Unknown Source)
at java.util.AbstractList$Itr.next(Unknown Source)
at set.problem.fourth.PoSet.makeTransitive(PoSet.java:145)
at set.problem.fourth.PoSet.addToR(PoSet.java:87)
at set.problem.fourth.PoSetDriver.typicalTesting(PoSetDriver.java:35)
at set.problem.fourth.PoSetDriver.main(PoSetDriver.java:13)
Run Code Online (Sandbox Code Playgroud)
小智 35
Java Collection类是快速失败的,这意味着如果在某个线程使用迭代器遍历它时将更改Collection,
iterator.next()则会抛出一个ConcurrentModificationException.在多线程以及单线程环境的情况下可能出现这种情况.- www.javacodegeeks.com
你不能修改List一个for/each循环,这是周围的语法糖Iterator作为一个实现细节.您只能.remove()在Iterator直接使用时安全地拨打电话.
请注意,Iterator.remove是在迭代期间修改集合的唯一安全方法; 如果在迭代进行过程中以任何其他方式修改基础集合,则行为未指定.- Java Collections教程
.add()在for/each循环内部调用会修改内容,而Iterator在幕后使用的内容会看到此内容并抛出此异常.
一个更微妙的问题是,你列出的第二种方式.size()是,每次你.add()最终处理你所有的事情都会增加.add(),这可能会导致无限循环,具体取决于输入数据是什么.我不确定这是不是你想要的.
解
我会创建另一个ArrayList和.add()所有新的东西,然后在循环之后,使用.addAll()原始ArrayList来将两个列表组合在一起.这将使你想要做的事情明确,除非你的意图是在你添加它们时处理所有新添加的东西.
始终使用Immutable集合类并构建新的Immutable集合类,而不是尝试修改单个共享类.这基本上是我2012年的回答,但我想让它更明确.
Guava非常支持这一点,用于ImmutableList.copyOf()传递数据.
用于Iterables.filter()将东西过滤成新的ImmutableList,没有共享的可变状态,意味着没有并发问题!
| 归档时间: |
|
| 查看次数: |
31682 次 |
| 最近记录: |