java - 如何在Java中迭代时在List中添加元素?
Posted
技术标签:
【中文标题】java - 如何在Java中迭代时在List中添加元素?【英文标题】:How to add element in List while iterating in java? 【发布时间】:2012-06-26 00:01:23 【问题描述】:假设我有一个类似的列表:
List<String> list = new ArrayList<>();
list.add("a");
list.add("h");
list.add("f");
list.add("s");
在遍历此列表时,我想在列表末尾添加一个元素。但我不想遍历新添加的元素,我想迭代到列表的初始大小。
for (String s : list)
/* Here I want to add new element if needed while iterating */
谁能建议我如何做到这一点?
【问题讨论】:
【参考方案1】:您不能为此使用 foreach 语句。 foreach 在内部使用了一个迭代器:
这个类的迭代器和listIterator返回的迭代器 方法是快速失败的:如果列表在任何结构上被修改 迭代器创建后的时间,除了通过 迭代器自己的删除或添加方法,迭代器会抛出一个 ConcurrentModificationException。
(来自 ArrayList javadoc)
在 foreach 语句中,您无权访问迭代器的 add 方法,并且无论如何这仍然不是您想要的 add 类型,因为它不会在末尾追加。您需要手动遍历列表:
int listSize = list.size();
for(int i = 0; i < listSize; ++i)
list.add("whatever");
请注意,这仅对允许随机访问的列表有效。您可以通过检查列表是否实现 RandomAccess 标记接口来检查此功能。 ArrayList 具有随机访问权限。链表没有。
【讨论】:
【参考方案2】:遍历列表的副本并将新元素添加到原始列表中。
for (String s : new ArrayList<String>(list))
list.add("u");
看 How to make a copy of ArrayList object which is type of List?
【讨论】:
【参考方案3】:只需迭代老式方式,因为您需要显式索引处理:
List myList = ...
...
int length = myList.size();
for(int i = 0; i < length; i++)
String s = myList.get(i);
// add items here, if you want to
【讨论】:
不,不会。它会在使用迭代器并在迭代时添加元素时,但在您自己进行迭代时不会。 OPs 想要“迭代到初始大小”。【参考方案4】:您可以迭代原始列表的副本(克隆):
List<String> copy = new ArrayList<String>(list);
for (String s : copy)
// And if you have to add an element to the list, add it to the original one:
list.add("some element");
请注意,在对列表进行迭代时甚至不可能将新元素添加到列表中,因为这将导致 ConcurrentModificationException
。
【讨论】:
【参考方案5】:我通过将元素添加到一个新的空 tmp 列表中,然后使用 addAll()
将 tmp 列表添加到原始列表中来做到这一点。这可以防止不必要地复制大型源列表。
想象一下当 OP 的原始列表中有几百万个项目时会发生什么;有一段时间你会吸收两倍的内存。
除了节省资源之外,这种技术还可以防止我们不得不求助于 80 年代风格的 for 循环和使用在某些情况下可能没有吸引力的有效数组索引。
【讨论】:
【参考方案6】:为了帮助解决这个问题,我创建了一个函数来更容易实现它。
public static <T> void forEachCurrent(List<T> list, Consumer<T> action)
final int size = list.size();
for (int i = 0; i < size; i++)
action.accept(list.get(i));
例子
List<String> l = new ArrayList<>();
l.add("1");
l.add("2");
l.add("3");
forEachCurrent(l, e ->
l.add(e + "A");
l.add(e + "B");
l.add(e + "C");
);
l.forEach(System.out::println);
【讨论】:
以上是关于java - 如何在Java中迭代时在List中添加元素?的主要内容,如果未能解决你的问题,请参考以下文章
在列表迭代期间从 java.util.List 中删除元素时引发 ConcurrentModificationException? [复制]