Java 基础 - List 遍历时为什么不能通过 for 循环进行删除,而使用 Iterator 可以 ?

本文详细探讨了在Java中遍历List时进行添加和删除操作的各种情况,包括普通for循环、增强for循环以及使用Iterator。通过源码分析,解释了为何在不同遍历方式下操作可能导致数据遗漏或抛出`ConcurrentModificationException`异常。同时,介绍了Iterator和ListIterator在遍历过程中的工作原理,以及如何安全地进行数据操作。
摘要由CSDN通过智能技术生成

说明

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])
  • 6
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java中,有多种方法可以将两个List集合进行拼接。 方法一是通过遍历集合中的元素,并在遍历的过程中完成添加操作。可以使用for-each循环遍历第一个List集合,将每个元素添加到新的List集合中,然后再遍历第二个List集合,将每个元素也添加到新的List集合中。最后,输出新的List集合即可。\[1\] 方法二是使用addAll()方法,该方法可以将一个集合中的所有元素添加到另一个集合中。可以先创建一个新的List集合,然后使用addAll()方法将第一个List集合和第二个List集合的元素都添加到新的List集合中。最后,输出新的List集合即可。\[2\] 另外,如果需要拼接的字段是字符串类型,可以先将要拼接的字段全部拼接起来,不管值是否为空。可以使用split()方法将字符串拆分成数组,然后将数组转换为List集合。接着,可以使用Stream流对List集合进行过滤,去除值为"null"和空字符串的元素,得到最终的List集合。\[3\] 以上是几种常见的Java List集合拼接方法,你可以根据具体的需求选择适合的方法来实现拼接操作。 #### 引用[.reference_title] - *1* *2* [JAVA中将两个列表(List)合并为一个列表](https://blog.csdn.net/JB666M/article/details/124467012)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [JAVA-List对象多个字段值拼接](https://blog.csdn.net/weixin_46690278/article/details/128232967)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值