说明
List 在遍历时可以进行添加,删除操作吗?为什么?Iterator 是什么?可以进行上述操作吗?知道底层原理吗?
以上问题是我在面试时碰到的,在本篇博文中,我将通过源码对 List 遍历时的添加,删除操作的相关知识点进行总结。
注意,这里的操作都是针对正在遍历的 List 自身的操作。
首先,回答以上问题:
-
在普通的 for 循环中,可以进行数据的添加操作,但不能进行删除操作。
-
在增强的 for 循环中,既不能进行添加操作,也不能进行删除操作。
-
通过 Iterator 及相关扩展类,可以进行添加或删除操作。
接下来,我将通过示例和源码来解释为什么。
正文
普通 for 循环
在普通 for 循环中,可以进行数据的添加,但是不能删除删除。原因是在删除时,由于坐标值的增加,会导致数据遗漏。
示例:
public static void main(String[] args) {
List<Integer> nums = new ArrayList<>();
nums.add(1);
nums.add(2);
nums.add(3);
nums.add(4);
for (int i = 0; i < nums.size(); i++) {
Integer num = nums.get(i);
System.out.println(num);
if (num.equals(2)) {
nums.remove(num);
}
}
}
---- 输出 ----
1
2
4
可以看到,在删除 2 后,下一个元素 3 在遍历时被遗漏了。
这是因为在删除 2 后,剩余的元素会整体向前移动一位,而坐标值仍是递增的,所以下一个坐标元素值相当于当前删除元素的下下一位元素值。对此,我们可以在删除元素时,将坐标值减 1。
if (num.equals(2)) {
nums.remove(num);
i--;
}
List.remove
在以上示例中,我使用的是 ArrayList.remove(Object o) 方法,该方法会移除 List 中第一个满足目标值的元素。
// Removes the first occurrence of the specified element from this list, if it is present.
public boolean remove(Object o) {
if (o == null) {
for (int index = 0; index < size; index++)
if (elementData[index] == null) {
fastRemove(index);
return true;
}
} else {
for (int index = 0; index < size; index++)
if (o.equals(elementData[index])