Java遍历集合元素并修改

这篇具有很好参考价值的文章主要介绍了Java遍历集合元素并修改。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

结论:fori循环可以修改、删除、添加,但是要注意的是下标还是元素;增强for循环内,可以修改,不可以删除、添加。想要删除、添加,使用集合迭代器的删除、添加方法。

对List和Set的遍历,有四种方式,下面以ArrayList为例进行说明。

1.1 fori循环
使用普通for循环的遍历方式效率最高,尽量将循环无关的代码放置在集合外执行。

代码如下:

for (int i = 0; i < list.size(); i++) {
    System.out.println(i);
}

如果要在普通for循环里对集合元素进行删除操作,可能会出现问题:

public static void main(String[] args) {
    List<Integer> list = new ArrayList<Integer>();
    list.add(1);
    list.add(2);
    list.add(2);
    list.add(4);
    list.add(5);
    for (int i = 0; i < list.size(); i++) {
        if (list.get(i) == 2) {
            list.remove(i);
        }
    }
    System.out.println(list);
}
//运行结果如下:

//[1, 2, 4, 5]

结果说明:

集合中有两个值为2的元素,但是在代码执行之后,值为2的元素并没有完全移除。

在第一次删除后,集合发生了改变,删除位置之后的所有元素都向前挪动了一个位置,删除位置上的元素由下一位置上的元素替代。

在下次遍历时,从删除位置后开始判断,跳过了删除位置上的元素,从而导致最后打印的结果和预期的不一致。

改进的办法是在删除之后设置索引减1,重新判断删除位置上的元素。

1.2 增强for循环
进一步精简了遍历的代码,底层使用迭代器。

代码如下:

for (Integer i : list) {
    System.out.println(i);
}

如果在增强for循环里删除或者添加集合元素,那么一定会报异常:

public static void main(String[] args) {
    List<Integer> list = new ArrayList<Integer>();
    list.add(1);
    list.add(2);
    list.add(2);
    list.add(4);
    list.add(5);
    for (Integer i : list) {
        if (i == 2) {
            list.remove(i);
        }
    }
    System.out.println(list);
}
//运行结果如下:

//java.util.ConcurrentModificationException

结果说明:

抛出ConcurrentModificationException异常是由快速失败(fail-fast)机制引起的,该机制是为了避免在遍历集合时,对集合的结构进行修改。

快速失败机制使用modCount记录集合的修改次数,在删除时除了删除对应元素外,还会更新modCount。

增强for循环本质上是使用迭代器进行遍历,迭代器在初始化时会使用expectedModCount记录当时的modCount,遍历时会检查expectedModCount是否和modCount相同,如果不同就会抛出ConcurrentModificationException异常。

1.3 使用迭代器
代码如下:

Iterator<Integer> iterator = list.iterator();
while (iterator.hasNext()) {
    System.out.println(iterator.next());
}

如果在迭代器中使用集合提供的删除或添加方法,同样会报错:

public static void main(String[] args) {
    List<Integer> list = new ArrayList<Integer>();
    list.add(1);
    list.add(2);
    list.add(2);
    list.add(4);
    list.add(5);
    Iterator<Integer> iterator = list.iterator();
    while (iterator.hasNext()) {
        if (iterator.next() == 2) {
            list.add(6);
        }
    }
    System.out.println(list);
}
//运行结果如下:

//java.util.ConcurrentModificationException

结果说明:

这里抛出异常的原因和增强for循环一样,同样是因为快速失败机制。

解决办法是在迭代器中删除或添加元素时,使用迭代器提供的删除或添加方法,不要使用集合提供的删除或添加方法。

需要注意的是,普通迭代器中只提供了删除方法,在集合迭代器中还提供了添加和修改方法。

1.4 使用集合迭代器
代码如下:

ListIterator<Integer> iterator = list.listIterator();
while (iterator.hasNext()) {
    System.out.println(iterator.next());
}

在迭代器中使用迭代器提供的删除或添加方法:

public static void main(String[] args) {
    List<Integer> list = new ArrayList<Integer>();
    list.add(1);
    list.add(2);
    list.add(2);
    list.add(4);
    list.add(5);
    ListIterator<Integer> iterator = list.listIterator();
    while (iterator.hasNext()) {
        if (iterator.next() == 2) {
            iterator.remove();
        }
    }
    System.out.println(list);
}
//运行结果如下:

//[1, 4, 5]

结果说明:

迭代器提供的方法同时维护了modCount和expectedModCount,所以不会产生快速失败。

1.5 使用forEach方法
forEach方法是JDK1.8新增的方法,需要配合Lambda表达式使用,代码如下:

list.forEach(i -> System.out.println(i));

使用forEach方法遍历:

public static void main(String[] args) {
    List<Integer> list = new ArrayList<Integer>();
    list.add(1);
    list.add(2);
    list.add(2);
    list.add(4);
    list.add(5);
    list.forEach(i -> {
        if (i == 2) {
            list.remove(i);
        }
    });
    System.out.println(list);
}
//运行结果如下:

//java.util.ConcurrentModificationException

结果说明:

这里抛出异常的原因也是因为快速失败机制。文章来源地址https://www.toymoban.com/news/detail-457346.html

到了这里,关于Java遍历集合元素并修改的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • List 集合遍历过程中删除元素。这个坑踩一遍就不要再踩了!

    作为一名后端开发,不管采用什么语言 使用 List 集合的频率都非常高。 对 List 集合的遍历和遍历中操作数据也是家常便饭。 我从我使用的过程中对于此问题的思考与实践形成记录,与大家交流。有不对的地方,恳请大家指正。 List 集合的遍历有很多种方式,每一种遍历方式

    2024年02月12日
    浏览(40)
  • Python循环中删除元素技巧:避免迭代错误的新列表方法和倒序遍历

      在Python中,如果你在循环过程中边遍历边删除列表元素,可能会导致一些意外的结果,因为在循环中直接修改正在迭代的列表可能会导致迭代错误或不一致的结果。这是因为在修改列表的同时,迭代器可能会失效。 为了安全地遍历列表并删除元素,可以考虑使用新的列表来

    2024年01月17日
    浏览(53)
  • C 语言数组教程:定义、访问、修改、循环遍历及多维数组解析

    数组用于将多个值存储在单个变量中,而不是为每个值声明单独的变量。 要创建数组,请定义数据类型(例如 int )并指定数组名称,后面跟着方括号 [] 。 要将值插入其中,请使用逗号分隔的列表,并在花括号内使用: 现在我们已经创建了一个变量,其中包含一个包含四个

    2024年02月03日
    浏览(52)
  • 【 java 集合】使用迭代器 Iterator 遍历集合

    💖 作者简介:大家好,我是阿牛,全栈领域优质创作者。😜 📝 个人主页:馆主阿牛🔥 🎉 支持我:点赞👍+收藏⭐️+留言📝 📣 系列专栏:java 小白到高手的蜕变🍁 💬格言:要成为光,因为有怕黑的人!🔥 上两篇文章总结了集合体系以及Collection常用方法,本节我们来

    2024年02月07日
    浏览(53)
  • java遍历集合的方法

      java中,集合的遍历是一项基本且重要的技能。我们不仅要知道集合中元素的个数,还要知道元素的值,以及它们之间的关系。 在 Java中,如果需要遍历集合中的某个元素,可以使用以下方法: 1.通过 return语句将集合中元素都遍历一遍,最后得到一个新的集合。 1.先创建一

    2024年02月02日
    浏览(78)
  • Java基础——Map集合遍历方式

    (1)方式一:键找值 先获取Map集合的全部键的Set集合。 遍历键的Set集合,然后通过键提取对应值。 涉及API: 方法名称 说明 SetK keySet() 获取所有键的集合 V get(Object key) 根据键获取值 (2)方式二:键值对 先把Map集合转换成Set集合,Set集合中每个元素都是键值对实现类型了。

    2023年04月10日
    浏览(41)
  • java中collection的循环遍历

    2024年02月06日
    浏览(44)
  • 【Java】List集合遍历的五种方法

    🎊专栏【Java】 🌺每日一句:人生最重要的就是要清醒的认知 ⭐欢迎并且感谢大家指出我的问题 目录 1.通过for循环配合List接口中的size()和get(index i)的方法 2.使用Iterator迭代器及其方法遍历集合 🍔迭代器 🍔具体操作 3.增强for循环遍历 🍔是for循环的一种 🍔格式 🍔好处 🍔弊

    2024年02月03日
    浏览(56)
  • 【C++】【数据结构】循环队列的基本操作(初始化、入队、出队、取队头元素、遍历输出队列、求队列长度)顺序队列的算法实现【附全代码】

    使用c++完成数据结构循环队列的基本操作,包括(初始化、入队、出队、取队头元素、遍历输出队列、求队列长度等),可直接编译运行。 队列 又称为 “先进先出” (FIFO)线性表。限定插入操作只能在队尾进行,而删除操作只能在队首进行。 循环队列 ——采用 顺序存储结构

    2023年04月16日
    浏览(53)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包