Finder

  • 首页
  • 论坛
  • 网盘|中转站
  • 杂货店
  • 个人仪表盘
Godson的个人博客
发现自己,发现世界上一切美好的事物
  1. 首页
  2. 技术
  3. 正文

Java中关于集合动态修改异常的详细解释

2021年1月2日 566点热度 1人点赞 0条评论

问题描述

现在有这样一段代码:

image.png

这段代码中,我们创建了一个ArrayList类,并添加了一些字段。之后,使用迭代器来按照我们给定的条件(列表中存在“java”字段)来确认是否添加新的字段。看起来是一个很正确的程序,但在运行时。。。image.png

出现了异常。异常定位在列表的迭代器中checkForComodification这个方法。以下进行跟踪查看。

问题定位

image.png

可以看到。这是一个很简单的方法。这里的modCount和exceptedModCount变量分别在下面展示其定义。1.modCountimage.png

主要意思是这个变量,当集合更改就会变化,目的是防止外部通过迭代器改变集合,产生未预料到的后果。

2.exceptedModCount

image.png

可以看到,在迭代器初始化时,初始化exceptedModCount。且和前者的值相等。这样的话,一定是我们在调用某些方法后间接地修改了二者的值,使得checkForComodification这个方法抛出了异常。从异常信息中发现,Itr.next()方法抛出了异常:

Itr是在ArrayList中实现的迭代器方法。前往查看得知:

image.png

看起来,这个方法没有直接修改modCount和exceptedModCount变量的值,但是在开始执行使调用了可能产生异常的方法,因此可以肯定,是add(object e)方法出了问题。

image.png

可以看到,add(object e)方法执行时,会使得modCount+1,造成第二次使用next()方法时产生异常。

为什么会这样?

实际上,java中存在各种不同的容器(List,Set)因为容器的内部结构不同,很多时候可能不知道该怎样去遍历一个容器中的元素。所以为了使对容器内元素的操作更为简单,Java引入了迭代器模式,把访问逻辑不同类型的集合类中抽取出来,从而避免向外部暴露集合的内部结构。

当迭代器工作的过程中,不允许集合擅自修改集合结构,如果修改了会导致modCount值变化,从而不会等于expectedModCount,那么迭代器就会抛出并发修改异常。本例中,相当于从外部通过迭代器试图修改集合结构,因此产生异常。

解决方案

1.使用迭代器遍历,使用迭代器添加元素

使用while循环、hasNext()与next()方法遍历元素

使用ListIteractor接口中的add(object e)方法添加元素(实际上ListIteractor添加了add方法)

image.png

改写的程序如下:

image.png

2.使用集合遍历,使用集合添加元素

使用for循环、size()方法与get()方法遍历元素

使用add()方法添加元素

标签: java 学习 编程
最后更新:2021年3月3日

Godson

这个人很懒,什么都没留下

点赞
< 上一篇
下一篇 >

文章评论

取消回复

COPYRIGHT © 2022 Finder. ALL RIGHTS RESERVED.

Theme Kratos Made By Seaton Jiang

看板娘