List对象里删除元素报错原因求解

shirui8653719 2017-06-20 05:05:32
List<String> a = new ArrayList<String>();
a.add("1");
a.add("2");
for (String temp : a) {
if ("1".equals(temp)) {
a.remove(temp);
}
}

为什么第5行
if ("1".equals(temp))
这段代码不会报错,而
if ("2".equals(temp))
这段代码就会报错,谁能帮忙详细的解释一下,谢谢。
...全文
585 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
Jcon_ 2017-06-21
  • 打赏
  • 举报
回复
介绍两个删除的方法,如下:
	public static void main(String[] args) {
		List<String> list = new ArrayList<String>();
		list.add("1");
		list.add("2");
		list.add("3");
		list.add("3");
		
		//方法一
		System.out.println("方法一删除前:" + list);
		Iterator<String> iterator = list.iterator();
		while (iterator.hasNext()) {
			String next = iterator.next();
			if ("3".equals(next)) {
				iterator.remove();
			}
		}
		System.out.println("方法一删除后:" + list);
		
		//方法二
		System.out.println("方法二删除前:" + list);
		for (int i = 0; i < list.size(); i++) {
			if ("2".equals(list.get(i))) {
				list.remove(list.get(i));
				--i;
			}
		}
		System.out.println("方法二删除后:" + list);
	}
HinanaiTenshi 2017-06-21
  • 打赏
  • 举报
回复
引用 7 楼 shirui8653719 的回复:
引用 4 楼 HinanaiTenshi 的回复:
基础知识:如果需要在遍历一个集合的过程中删除此集合的元素,请使用迭代器。
我现在想问删除1为什么不会报错。
你可以先了解一下为何要用迭代器,迭代器避免的问题就是第一个比较没有出错的原因。
shirui8653719 2017-06-21
  • 打赏
  • 举报
回复
引用 3 楼 u014038116 的回复:
个人见解,在遍历的时候,会先调用 public boolean hasNext() { return cursor != size; },但你删除1后,准备再次遍历时,这首cursor==size,都为1,hasNext返回false,不会再次调用next,也就不会再去调用checkForComodification这个方法,当你删除2的后,curosr=2,size=1,会去调用next,也就报错了,你可以试下,删除list的倒数第二个元素应该都不会报错,其他的都会,不对勿喷
110成成 2017-06-21
  • 打赏
  • 举报
回复
见我之前回复的帖子,http://bbs.csdn.net/topics/392166133
shirui8653719 2017-06-21
  • 打赏
  • 举报
回复
引用 4 楼 HinanaiTenshi 的回复:
基础知识:如果需要在遍历一个集合的过程中删除此集合的元素,请使用迭代器。
我现在想问删除1为什么不会报错。
shirui8653719 2017-06-21
  • 打赏
  • 举报
回复
引用 5 楼 lyjcxy1990 的回复:
兄弟可以看下源码 增强for的底层还是用迭代器遍历的,迭代器实际上是集合的副本 在复制的时候会将集合内的计数器也一并进行复制,每一次使用迭代遍历集合中的元素 都会进行一次计数器的比较,也就是比较迭代器的计数器和集合的计数器是否相同 如果不同会产生并发修改异常 因为2是最后一个元素,所以此时迭代器遍历已经结束,所以再修改集合内容则不会报错 你可以试试再加几个元素,最后一个都是能成功的
现在2是会报错,1不会报错。
whhmkj 2017-06-21
  • 打赏
  • 举报
回复
明显基础没学好 list里面怎么能同时删除元素,list遍历是通过下标来操作的。你这个时候把其中一个删了,但下标没变
八二年的咸鱼 2017-06-20
  • 打赏
  • 举报
回复
兄弟可以看下源码 增强for的底层还是用迭代器遍历的,迭代器实际上是集合的副本 在复制的时候会将集合内的计数器也一并进行复制,每一次使用迭代遍历集合中的元素 都会进行一次计数器的比较,也就是比较迭代器的计数器和集合的计数器是否相同 如果不同会产生并发修改异常 因为2是最后一个元素,所以此时迭代器遍历已经结束,所以再修改集合内容则不会报错 你可以试试再加几个元素,最后一个都是能成功的
HinanaiTenshi 2017-06-20
  • 打赏
  • 举报
回复
基础知识:如果需要在遍历一个集合的过程中删除此集合的元素,请使用迭代器。
xiaovhao 2017-06-20
  • 打赏
  • 举报
回复
个人见解,在遍历的时候,会先调用 public boolean hasNext() { return cursor != size; },但你删除1后,准备再次遍历时,这首cursor==size,都为1,hasNext返回false,不会再次调用next,也就不会再去调用checkForComodification这个方法,当你删除2的后,curosr=2,size=1,会去调用next,也就报错了,你可以试下,删除list的倒数第二个元素应该都不会报错,其他的都会,不对勿喷
shirui8653719 2017-06-20
  • 打赏
  • 举报
回复
引用 1 楼 u014038116 的回复:
额,你可以去搜下ConcurrentModificationException产生的原因
嗯,搜过了,只讲了ConcurrentModificationException报错的原因,但是没有讲if ("1".equals(temp)) 不会报错的原因。
xiaovhao 2017-06-20
  • 打赏
  • 举报
回复
额,你可以去搜下ConcurrentModificationException产生的原因

67,515

社区成员

发帖
与我相关
我的任务
社区描述
J2EE只是Java企业应用。我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。
社区管理员
  • Java EE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧