Java - 在使用for索引循环迭代时删除列表中的元素

时间:2018-04-16 21:54:31

标签: java

我知道不建议在迭代时从列表中删除元素 最好使用iterator.remove(),java stream,或将remove复制到外部列表。

但是这个简单的代码才有效:

 static List<Integer> list = new ArrayList<Integer>();
 ...
 private static void removeForI() {
    for (int i = 0; i < 10; i++) {
        if (i == 3) {
            list.remove(i);
            continue;
        }
        System.out.println(i);
    }
 }

使用它是否安全?

4 个答案:

答案 0 :(得分:2)

您需要考虑list.remove(index)的工作原理。 调用remove(idx)时,idx索引处的元素将被删除,所有下一个元素将被移至左侧。 因此,假设您有一个包含2,3,3,4,5的列表。现在您要从此列表中删除所有3。但是如果你使用当前的方法,它将只删除第一次出现的3.因为在删除位于第1位的第3次出现后,你的内容将被移到左边,就像这样2,3,4,5。但是现在你的for循环会将当前索引增加到2,其中包含4而不是3。 这就是为什么不建议在迭代时删除项目,因为每次删除后项目的索引都会被更改。

编辑:此外,如果您在循环中断条件中使用常量值,如上例i<10;中所示,则可能会出现ArrayIndexOutOfBounds异常。

答案 1 :(得分:0)

即使它在人们指出的条件下工作,我也会暂时使用它并将其更改为:

private static void removeForI() {
    list.remove(3);
    list.foreach(System.out::println);
}

无需检查i == 3,只需在for循环之前删除它。

答案 2 :(得分:0)

看起来循环将在稍后具有不同的条件,否则您可以像JoschJava所说的那样简单地执行。

但是,如果您真的想要遍历所有元素并在循环期间删除特定元素,那么您可能希望之后向后移动索引。如果是这种情况,我会在条件机构的末尾添加:

i -= 1;

答案 3 :(得分:0)

根本不安全。如果您知道在迭代期间可能会对列表进行调整,请将列表对象转换为迭代器对象,然后使用其方法: hasNext,next,remove ...