如何在java中迭代时在List中添加元素?

时间:2012-06-24 12:13:48

标签: java collections arraylist loops

说我有一个像这样的列表:

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 */

有人可以建议我怎么做?

6 个答案:

答案 0 :(得分:39)

您无法使用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具有随机访问权限。链表不会。

答案 1 :(得分:8)

只需迭代旧式方式,因为您需要显式索引处理:

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
}

答案 2 :(得分:7)

遍历列表副本并将新元素添加到原始列表中。

for (String s : new ArrayList<String>(list))     
{
    list.add("u");
}

请参阅 How to make a copy of ArrayList object which is type of List?

答案 3 :(得分:3)

您可以迭代原始列表的副本(克隆):

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

答案 4 :(得分:1)

我是通过将元素添加到新的空tmp列表,然后使用addAll()将tmp列表添加到原始列表来实现的。这可以防止不必要地复制大型源列表。

想象一下当OP的原始列表中有几百万个项目时会发生什么;有一段时间你会把记忆吸得两倍。

除了节省资源之外,这种技术还可以防止我们不得不求助于80s风格的for循环并使用有效的数组索引,这些索引在某些情况下可能没有吸引力。

答案 5 :(得分:0)

为了帮助解决这个问题,我创建了一个函数来让这个更容易实现。

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);