为什么这段代码不能从ArrayList中删除所有奇数整数?

JTB*_*Bis -1 java arrays arraylist

我有一个10个正非零整数的ArrayList.

0: 1103
1: 711
2: 199
3: 1527
4: 1745
5: 1530
6: 984
7: 798
8: 927
9: 1986
Run Code Online (Sandbox Code Playgroud)

当我跑这个

for(int i = 0; i < l1.length; i++){
        int temp = l1.retrieveAt(i);
        int temp2 = temp % 2;
        if(temp2 == 1){
            l1.removeAt(i);
        }
    }
Run Code Online (Sandbox Code Playgroud)

列表更改为

0: 711
1: 1527
2: 1530
3: 984
4: 798
5: 1986
Run Code Online (Sandbox Code Playgroud)

L1是的目的UnorderedArrayList延伸ArrayListClass它实现ArrayListADT(点击引擎收录)

retrieveAt(index)并且removeAt(index)是ArrayListClass的方法.

Jus*_*ano 5

在使用该索引进行迭代时删除索引处的值可能会导致跳过元素.例如,如果我们删除索引处的元素0,列表将变为:

0: 711
1: 199      <--- next element to check
2: 1527
3: 1745
4: 1530
5: 984
6: 798
7: 927
8: 1986
Run Code Online (Sandbox Code Playgroud)

索引现在递增到1循环的下一次迭代,因此跳过新的第一个元素(711位置的元素0).这种模式重复其余的值.

一个选项是使用Iterator模式,如所有Java Collection类(例如ArrayList)所假设的那样.使用此样式,您可以按如下方式重写循环:

for (Iterator<Integer> it = l1.iterator(); it.hasNext(); ) {
    int temp = it.next();
    int temp2 = temp % 2;
    if (temp2 == 1) {
        it.remove();
    }
}
Run Code Online (Sandbox Code Playgroud)

正如phatfingers的回答所述,首先从最高值迭代将消除这个问题.循环将是相同的,但它将从最后一个索引(l1.length - 1)开始并继续直到它到达0.因此,指数将[9, 8, ..., 0]不是原始指数[0, 1, ..., 9].该解决方案的代码是:

for (int i = l1.length - 1; i >= 0; i--) {
    int temp = l1.retrieveAt(i);
    int temp2 = temp % 2;
    if(temp2 == 1){
        l1.removeAt(i);
    }
}
Run Code Online (Sandbox Code Playgroud)