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

时间:2018-04-04 18:01:16

标签: 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

当我运行时

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

列表更改为

0: 711
1: 1527
2: 1530
3: 984
4: 798
5: 1986

l1是UnorderedArrayList的一个对象,它扩展ArrayListClass,实现ArrayListADT(点击进入pastebin)

retrieveAt(index)removeAt(index)是ArrayListClass的方法。

3 个答案:

答案 0 :(得分:5)

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

0: 711
1: 199      <--- next element to check
2: 1527
3: 1745
4: 1530
5: 984
6: 798
7: 927
8: 1986

对于循环的下一次迭代,索引现在递增到1,因此新的第一个元素(711,即 new 位置的元素{ {1}})被跳过。这种模式会重复其余的值。

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

ArrayList

正如 phatfingers 的回答所述,首先从最高值迭代会消除此问题。循环将是相同的,但它将从最后一个索引(for (Iterator<Integer> it = l1.iterator(); it.hasNext(); ) { int temp = it.next(); int temp2 = temp % 2; if (temp2 == 1) { it.remove(); } } )开始并继续直到它达到l1.length - 1。因此,索引将是0而不是原始[9, 8, ..., 0]。此解决方案的代码为:

[0, 1, ..., 9]

答案 1 :(得分:2)

[我正在修改我的答案。]

从列表中删除项目后,其下方的所有项目都会向上移动,因此您最终会在每次删除时跳过下一项,因为它会转移到您刚刚处理的索引中。如果你从下往上工作,你就不会遇到这个问题。

这是一些示例代码。 (作为对其他人的提醒,这是基于OP的专有类,而不是基于标准的ArrayList):

for (int i=l1.length-1; i>=0; i--) {
    if ((l1.retrieveAt(i)&1) == l) 11.removeAt(i);
}

答案 2 :(得分:0)

当您致电l1.removeAt(i)时,会更改其余元素的索引。

不会检查711的值,因为您只检查位置0一次,并删除位置0处的奇数元素.711移动到位置0,并继续从位置1进行检查。