java - 在当前“while (iterator.hasNext())”循环中添加到迭代器
问题描述
在下面的代码中,我希望迭代运行 3 次。起初,迭代器有 1 个“下一个”,但在第一次迭代期间,又向迭代器添加了两个值,因此应该还有两个“下一个”,即iterator.hasNext()
应该为真。
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
public class Foo {
public static void main(String[] args) {
List<String> strings = new ArrayList<>();
strings.add("A");
ListIterator<String> iterator = strings.listIterator();
int i = 0;
while (iterator.hasNext()) {
i++;
String str = iterator.next();
if (str.equals("A")) {
iterator.add("B");
iterator.add("C");
}
// strings.remove(str);
// iterator = strings.listIterator();
}
System.out.println("The iteration was run " + i + " times");
}
}
但它只运行一次。作为一种解决方法,我可以从原始列表中删除当前迭代,然后重置迭代器(注释行)。但为什么这是必要的?迭代器不应该已经知道它有更多的值要迭代吗?
解决方案
迭代器不应该已经知道它有更多的值要迭代吗?
不,不应该。如果您查看add()
此处的文档,则可以在此处找到以下句子
对 next 的后续调用将不受影响,对 previous 的后续调用将返回新元素。(此调用将调用 nextIndex 或 previousIndex 返回的值加一。)
它清楚地表明添加新元素不会影响您当前的循环流程。此外,如果您查看ListIterator
实现的源代码ArrayList
:
...
public E next() {
checkForComodification();
int i = cursor;
if (i >= SubList.this.size)
throw new NoSuchElementException();
Object[] elementData = ArrayList.this.elementData;
if (offset + i >= elementData.length)
throw new ConcurrentModificationException();
cursor = i + 1;
return (E) elementData[offset + (lastRet = i)];
}
public void add(E e) {
checkForComodification();
try {
int i = cursor;
SubList.this.add(i, e);
cursor = i + 1;
lastRet = -1;
expectedModCount = ArrayList.this.modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
cursor
变量指向一个用于next()
返回下一个元素的位置。如您所见,两者cursor
和SubList
size 都增加了。所以,实际上,cursor
被调整为跳过“旧”下一个位置,转而支持“新”下一个位置。每次add()
调用,cursor
都会相应地进行调整。要获得新元素,您应该使用previous()
或重新开始循环。
此外,您的案例可以说明如下:
cursor
|
V
0 1
A
添加和之后B
,仍然指向一个不存在的元素:C
cursor
cursor
|
V
0 1 2 3
A B C
推荐阅读
- amazon-web-services - AWS Config - 资源发现停留在“正在发现您的资源”
- r - 使用“模型”函数调用模型/变量进行预测时如何使用字符值?
- windows - 我在哪里可以看到失败的 Docker Desktop Windows 安装的日志文件?
- javascript - 过滤问题,ASP.NET Kendo UI,多选(多复选框)Kendo UI GRID
- php - Woocommerce 持久购物车
- masstransit - 记录处理的 MassTransit Saga 异常
- python - 删除列的功能
- google-apps-script - 使用 Google 表格宏创建具有计数聚合的图表时出现意外行为
- python - 用于为 HttpResponse 创建受密码保护的 zip 内存的 Python 代码
- java - 无法从相关类调用所需的方法