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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

        记得以前回复过一个相关的问题,是在完成相关视频之前,本来是想找一下回复修改过来的,不过没找到帖子,,,,
        这里贴出相关理论知识吧(有必要掌握),下次见到的话,有机会帮助修改过来。
问题描述:
  • 一个集合,想判断里面有没有"world"这个元素,如果有,添加一个"javaee"元素,请写代码实现。
  1. List list = new ArrayList();
  2.             list.add("a");
  3.             list.add("b");
  4.             list.add("world");
  5.             list.add("d");
  6.             list.add("e");
  7.             
  8. Iterator it = list.iterator();
  9.             while(it.hasNext()) {
  10.         String str = (String)it.next();
  11.         if(str.equals("world")) {
  12.                list.add("javaee");   //这里会抛出ConcurrentModificationException并发修改异常,遍历的同时,在增加元素。并发修改
  13.         }
  14.             }
复制代码
(刚开始很容易想到这样实现,,,)
  • 但是,有ConcurrentModificationException出现

解决方案:
  • 迭代器迭代元素,迭代器修改元素(ListIterator的特有功能add)

  1. ListIterator lit = list.listIterator();        //如果想在遍历的过程中添加元素,可以用ListIterator中的add方法
  2.             while(lit.hasNext()) {
  3.         String str = (String)lit.next();
  4.         if(str.equals("world")) {
  5.                 lit.add("javaee");   
  6.         }
  7.             }
复制代码



5 个回复

倒序浏览
勿忘`初心 来自手机 高级黑马 2016-7-9 12:12:52
沙发
底层原理是什么呢?这些有点懵逼
回复 使用道具 举报
勿忘`初心 发表于 2016-7-9 12:12
底层原理是什么呢?这些有点懵逼

建议,先记着怎么用,等熟练了再往深层次研究。
不然很容易搞混,建议逐层深入 {:3_56:}
回复 使用道具 举报
本帖最后由 我是你岁哥❤环 于 2016-7-9 13:12 编辑

并发修改异常  ConcurrentModificationException, 这个异常时迭代器对象抛出的,出现的原因是集合中增加了元素到会迭代器预期的迭代次数发生改变,导致迭代器的结果不准确.另外一种解决方式:
从业务逻辑上讲,我们只要找到 "world" 这个元素,至于后面还有多少个元素我们并不关心,所以只需要找到这个元素后跳出循环不在迭代即可
  1. Iterator it = list.iterator();
  2. while(it.hasNext()) {
  3.         String str = (String)it.next();
  4.         if(str.equals("world")) {
  5.                list.add("javaee");  
  6.                break;
  7.         }
  8. }
复制代码
在使用break语句跳出循环后,由于没有继续使用迭代器对集合中的元素进行迭代,因此,集合中增加的元素对程序没有任何影响,不会出现异常


回复 使用道具 举报 1 0
本帖最后由 cat73 于 2016-7-9 13:36 编辑
我是你岁哥❤环 发表于 2016-7-9 13:11
并发修改异常  ConcurrentModificationException, 这个异常时迭代器对象抛出的,出现的原因是集合中增加了元 ...

我认为不同逻辑还是分离的好

一块代码专门负责找 world,如果找到则设置 found = true

下面的代码再去根据这个 found 去进行后续的修改

  1.     private void test() {
  2.         List<String> list = new ArrayList<>();
  3.         list.add("a");
  4.         list.add("b");
  5.         list.add("world");
  6.         list.add("d");
  7.         list.add("e");
  8.         
  9.         if (equalsContains(list, "world")) {
  10.             list.add("javaee");
  11.         }
  12.     }
  13.    
  14.     private <T> boolean equalsContains(Collection<T> collection, T t) {
  15.         for(T t2 : collection) {
  16.             if(t.equals(t2)) {
  17.                 return true;
  18.             }
  19.         }
  20.         return false;
  21.     }
复制代码
回复 使用道具 举报 1 0
我是你岁哥❤环 发表于 2016-7-9 13:11
并发修改异常  ConcurrentModificationException, 这个异常时迭代器对象抛出的,出现的原因是集合中增加了元 ...

那么开发中比较常用的是那种方式呢?
(1)List、Break结合
(2)使用 ListIterator(ListIterator)
(3)求指导{:3_56:}
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马