java - 移动迭代器语句使代码编译
问题描述
我创建了一个基本上只是测试近似值的代码。ArrayLists 的运行时。但是,如果一行代码被移动点,代码将无法编译。这是编译的代码。
public class ArrayTest {
public static void main(String []args) {
ArrayListTest();
}
private static void ArrayListTest() {
//initializes random variable, accumulator and iterator and ArrayList
Random rand = new Random();
Float accum = 0F;
ArrayList<Float> al = new ArrayList<>();
//finds time of program pre-running
long startTime = System.currentTimeMillis();
//Populates ArrayList
for (int i = 0; i < 20000000; i++) al.add(rand.nextFloat());
//finds time of program post-running
long endTime = System.currentTimeMillis();
//Iterates through ArrayList, summing elements
Iterator<Float> itr = al.iterator();
while(itr.hasNext()) {
accum += itr.next();
}
//Finds time of summing ArrayList
long sumEndTime = System.currentTimeMillis() - endTime;
//Prints meaningful conclusion
System.out.print("ArrayList takes: " + (endTime - startTime) / 1000.0 + " seconds to initialize.\n");
System.out.print("ArrayList takes: " + (sumEndTime / 1000.0) + " second to sum. \n");
}
}
但是,如果您移动“Iterator itr = al.iterator();” 在数组列表声明之后,它不会编译。为什么是这样?
解决方案
如果您将迭代器创建移动到 ArrayList 创建之后,您的代码编译得很好,并且代码将运行,但它会抛出 ConcurrentModificationException ,因为您在创建迭代器之后更改列表并且不使用迭代器这样做。这将使迭代器处于无效状态。
如果您在此处创建迭代器:
ArrayList<Float> al = new ArrayList<>();
Iterator<Float> itr = al.iterator();
然后在此处添加到 ArrayList:
// Populates ArrayList
for (int i = 0; i < 20000000; i++)
al.add(rand.nextFloat());
迭代器现在正尝试遍历自创建以来已更改的集合,这将导致在此处抛出 ConcurrentModificationException:
while (itr.hasNext()) {
accum += itr.next();
}
要解决此问题,请仅在创建迭代器后使用迭代器修改集合。这主要在从集合中删除项目时完成。如果您需要添加项目,则需要使用 ListIterator,而不是普通的迭代器,或者在填充集合后简单地创建迭代器。
例如,
ArrayList<Float> al = new ArrayList<>();
// Iterator<Float> itr = al.iterator();
ListIterator<Float> listItr = al.listIterator();
long startTime = System.currentTimeMillis();
for (int i = 0; i < 20000000; i++) {
// al.add(rand.nextFloat());
listItr.add(rand.nextFloat()); // add with the ListIterator
}
long endTime = System.currentTimeMillis();
while (listItr.hasNext()) {
accum += listItr.next();
}
您还需要阅读:运行时错误和编译器错误有什么区别?
因为这种区别非常重要,尤其是在本网站上询问时。它们是两个非常不同的广泛错误类别,并且在大多数情况下,它们不重叠。
推荐阅读
- actionscript-3 - 设置临时文件的文件扩展名
- ubuntu - 替换字符 (�) 在 Libra Office 中出现,而在 CSV 文件中的 Google 电子表格中为“'”
- python - 捕获外部程序的连续输出
- ios - 斯威夫特认为非零值实际上是零
- jsp - c:out 没有在 jsp 文件中给出输出
- python - 生成对象问题
- logging - 有什么方法可以添加限制数据以使用winston记录
- laravel - Laravel 测试记住我 cookie
- wpf - DataGrid AutoGenerateColumns 错误模板
- neo4j - 如何修复错误“Neo.ClientError.Statement.SemanticError:无法使用名称的空属性值合并节点”?