fori 方式
(错误的遍历方式)
fori 正向遍历方式是通过获取ArrayList的底层数组通过下标进行遍历。
这种方法进行遍历删除指定元素,虽然不会报错,但是元素数据有误。
List<Integer> list = CollUtil.newArrayList(1, 2, 3, 4, 5);
@Test
public void testList() {
for (int i = 0; i< list.size(); i++) {
list.remove(i);
}
System.out.println(list.size());
System.out.println(list.toString());
}
// 结果:
// size: 2
// toString: [2, 4]
虽然在遍历中删除所有元素,但是最后结果却有两个值。查看源码remove(int index)
public E get(int index) {
rangeCheck(index);
// 直接返回对应下标的元素
return elementData(index);
}
// remove删除指定下标的元素
public E remove(int index) {
rangeCheck(index);
modCount++;
E oldValue = elementData(index);
// 计算需要移动的数组长度
int numMoved = size - index - 1;
if (numMoved > 0)
// 如果大于0,将ArrayList内的数组复制移动,将指定下标元素的后面所有元素(numMoved)向前移动一个位置
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
// 长度减一
elementData[--size] = null; // clear to let GC do its work
return oldValue;
}
因此,通过下标正向遍历,当删除了指定下标的元素后,下标后的元素数组向前移动一个位置。通过局部变量i对应的元素,虽然坐标不变,但是坐标对应的元素已经是后面一个元素了,再进行 i++ 操作,就会跳过当前元素。导致遍历删除后的元素数据错误。
根据这个原因,可以通过fori的倒叙遍历方式,进行正确的遍历删除