A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© ixiangfeng 金牌黑马   /  2013-10-15 16:09  /  1501 人查看  /  10 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 ixiangfeng 于 2013-10-15 20:34 编辑

  1. import java.util.*;
  2. public class IteratorErrorTest
  3. {
  4. public static void main(String[] args) throws Exception
  5. {
  6. //创建一个集合
  7. Collection books = new HashSet();
  8. books.add("轻量级Java EE企业应用实战");
  9. books.add("疯狂Java讲义");//(1)
  10. books.add("疯狂Android讲义");//(2)
  11. //获取books集合对应的迭代器
  12. Iterator it = books.iterator();
  13. while(it.hasNext())
  14. {
  15. String book = (String)it.next();
  16. System.out.println(book);
  17. if (book.equals("疯狂Android讲义"))
  18. {
  19. //使用Iterator迭代过程中,不可修改集合元素,下面代码引发异常
  20. books.remove(book);
  21. }
  22. }
  23. System.out.println(books);
  24. }
  25. }

复制代码
结果:
  1. 轻量级Java EE企业应用实战
  2. 疯狂Android讲义
  3. Exception in thread "main" java.util.ConcurrentModificationException
  4. at java.util.HashMap$$$$$$$$$$$$$$$$HashIterator.nextEntry(HashMap.java:806)
  5. at java.util.HashMap$$$$$$$$$$$$$$$$KeyIterator.next(HashMap.java:841)
  6. at IteratorErrorTest.main(IteratorErrorTest.java:26)

复制代码
为什么没有输出 "疯狂Java讲义" 而能输出 "疯狂Android讲义" ?  
HashSet集合不是应该没有顺序的吗?
把(1)和(2)行代码顺序换一下不会有异常出现,为什么?


评分

参与人数 1技术分 +1 收起 理由
李江 + 1

查看全部评分

10 个回复

正序浏览
小痞痞 发表于 2013-10-15 20:22
如果想具体的了解是按照怎样的函数随机的那就得去了解他的底层代码了

好吧 thx
回复 使用道具 举报
ixiangfeng 发表于 2013-10-15 19:40
我发现把第10行的 books.add("疯狂Java讲义");  改成  books.add("疯狂JAVA");  只是改变里面的内容小写 ...

如果想具体的了解是按照怎样的函数随机的那就得去了解他的底层代码了
回复 使用道具 举报
雷丹 发表于 2013-10-15 19:27
直接用for循环代替iterator

我也知道可以用foreach循环来代替Iterator遍历集合,不过我是想弄明白这个问题,而且for循环在迭代访问集合元素时集合改变也是一样会引发异常的吧
回复 使用道具 举报
小痞痞 发表于 2013-10-15 19:20
本来Hashset就是无序的   但是当你添加的顺序和集合本身计算的顺序一样的时候你看就就成有序的了
像下边 ...

我发现把第10行的 books.add("疯狂Java讲义");  改成  books.add("疯狂JAVA");  只是改变里面的内容小写变大写了, 然后就可以编译运行,没有异常了  我是不是可以理解为在Iterator迭代过程中删除集合元素引发异常是伪随机性的,跟集合里面的对象有关?
回复 使用道具 举报
雷丹 中级黑马 2013-10-15 19:27:30
7#
直接用for循环代替iterator
回复 使用道具 举报
ixiangfeng 发表于 2013-10-15 19:01
如果不加if语句输出的是
轻量级Java EE企业应用实战
疯狂Android讲义

本来Hashset就是无序的   但是当你添加的顺序和集合本身计算的顺序一样的时候你看就就成有序的了
像下边我的那段代码  最后输出的顺序是
轻量级Java EE
轻量级Java EE企业应用实战
轻量级Java EE企业
疯狂Java讲义
疯狂Android讲义
回复 使用道具 举报
仇邓强 发表于 2013-10-15 19:14
楼主你好,如果问题已解决请将帖子状态修改为提问结束,如果未解决请继续提问,谢谢合作
如果不会修改请看 ...

我上面还有提问啊?
回复 使用道具 举报
To 金牌黑马 2013-10-15 19:14:23
板凳
楼主你好,如果问题已解决请将帖子状态修改为提问结束,如果未解决请继续提问,谢谢合作
如果不会修改请看解释帖:http://bbs.itheima.com/thread-89313-1-1.html
回复 使用道具 举报
小痞痞 发表于 2013-10-15 18:06
如果不加if语句输出的是
轻量级Java EE企业应用实战
疯狂Android讲义

如果不加if语句输出的是
轻量级Java EE企业应用实战
疯狂Android讲义
疯狂Java讲义

为什么是这个顺序输出呢? HashSet不是没有顺序的吗?
回复 使用道具 举报
如果不加if语句输出的是
轻量级Java EE企业应用实战
疯狂Android讲义
疯狂Java讲义

当运行到疯狂android讲义并在17行的代码中输出时
运行到if语句就直接报错
程序就没有继续运行了
所以程序还没有执行到疯狂android讲义后边的it.next()  也就是获取疯狂java讲义的时候程序就已经挂了
所以没有输出疯狂java讲义
而24行的输出语句根本得不到执行


把(1)和(2)行代码顺序换一下不会有异常出现,为什么?
这个貌似是新特性  具体的还没有研究出来    就是删除的如果是倒数第二个添加的就不会报错
  1. package cn.itcast.test.code;


  2. import java.util.Collection;
  3. import java.util.HashSet;
  4. import java.util.Iterator;

  5. public class Test {
  6.         public static void main(String[] args) throws Exception {
  7.                 // 创建一个集合
  8.                 Collection books = new HashSet();
  9.                 books.add("轻量级Java EE企业应用实战");
  10.                 books.add("轻量级Java EE企业");
  11.                 books.add("轻量级Java EE");
  12.                 books.add("疯狂Android讲义");// (2)
  13.                 books.add("疯狂Java讲义");// (1)
  14.                 // 获取books集合对应的迭代器
  15.                 Iterator it = books.iterator();
  16.                 while (it.hasNext()) {
  17.                         String book = (String) it.next();
  18.                         System.out.println(book);
  19.                         if ("疯狂Android讲义".equals(book)) {
  20.                                  //使用Iterator迭代过程中,不可修改集合元素,下面代码引发异常
  21.                                 books.remove(book);
  22.                         }
  23.                 }
  24.                 System.out.println(books);
  25.         }
  26. }
复制代码
就像这样还是不会报错的

个人理解是当运行到倒数第二个是刚好下边执行了remove
而在进行hasnext  就为false    所以循环就结束了

评分

参与人数 1技术分 +1 收起 理由
To + 1 很给力!

查看全部评分

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马