`
langyu
  • 浏览: 890488 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

[Java拾遗]迭代list过程中删除元素

    博客分类:
  • java
 
阅读更多
        今天在翻看HDFS中FSImage初始化部分时,其中有段代码是这样的:
for (URI dirName : fsNameDirs) {
      boolean isAlsoEdits = false;
      for (URI editsDirName : fsEditsDirs) {
          if (editsDirName.compareTo(dirName) == 0) {
               isAlsoEdits = true;
               fsEditsDirs.remove(editsDirName);
               break;
          }
      }
}

        根据以往经验,这段代码可能会有ConcurrentModificationException发生。在向他们指出这个问题前,我写了简单几句测试代码来提前验证下。

        代码一:

List<String> list = new ArrayList<String>();
list.add("a");
list.add("b");
list.add("c");
		
for (String str : list) {
    if (str.equals("a")) {
	    list.remove(str);
    }
}
		
System.out.println(list);

        代码一的结果如预期抛出异常。因为在迭代过程中再去删除元素,会造成迭代索引有问题。于是我又随手修改了下判断条件,删除list不同位置的元素。大家看下面这个例子,它的结果应该是什么?


        代码二:

List<String> list = new ArrayList<String>();
list.add("a");
list.add("b");
list.add("c");
		
for (String str : list) {
    if (str.equals("b")) {
	   list.remove(str);
    }
}
		
System.out.println(list);

        代码二的运行结果是正常的:[a, c]。

        这让我比较迷惑了。接着试了几次后发现,在一个list中,只有删除倒数第二个元素时是正常的,删除其它位置都会有异常抛出。于是我翻看了AbstractList中的迭代实现,主体是下面这三段代码


public boolean hasNext() {
    return cursor != size();
}

public E next() {
    checkForComodification();
    try {
         E next = get(cursor++);
         return next;
     } catch (IndexOutOfBoundsException e) {
         checkForComodification();
         throw new NoSuchElementException();
     }
}

final void checkForComodification() {
    if (modCount != expectedModCount)
         throw new ConcurrentModificationException();
    }
}

       cursor标示着当前list的索引,不断地与list size比对。如果hasNext返回true,会紧接着执行next方法,在next方法中检查当前list有没有被修改过。

        在list迭代过程中,如果删除一个元素,那么size就减一,hasNext提前结束,迭代不会到达list的最后一个元素。也就是说,如果在迭代到list倒数第二个元素时删除此元素,接下来的hasNext会返回false,迭代结束,不会进入next方法中做检查,也就不会出什么问题。而除此之外的其它情况下,hasNext都是true,接下来的next方法检查时会产生异常。

        问题让我很疑惑,但分析后的原理很简单。惟一感觉与平时想法不一样的地方是它对hasNext的判断条件有些奇怪。它没有以cursor小于list size来判断,而是取它俩是否相等,在cursor超过size时,又在从list中get元素时施以IndexOutOfBound的弥补。
2
2
分享到:
评论
1 楼 langyu 2011-07-25  
hdfs code中有break,所以没有上文所述的情况发生,但我们这里说的重点是如何next及检验不同

相关推荐

    [Java拾遗]Java对象大小探究

    NULL 博文链接:https://langyu.iteye.com/blog/1167581

    Java知识拾遗:三大框架的技术起源

    Java知识拾遗:三大框架的技术起源 本篇文章主要讲述了Java开发中三大框架的技术起源,即Struts、Hibernate和Spring框架。这些框架是我们Java开发中的常用的框架,它们分别针对不同的应用场景给出最合适的解决方案...

    09.java基础拾遗--类的加载和对象的构造过程.mp4

    09.java基础拾遗--类的加载和对象的构造过程.mp4

    java回顾、知识整理、拾遗、面试_java-review.zip

    拾遗部分则是对Java中一些较为偏僻但又可能在实际开发中遇到的知识点进行整理,如Java中的设计模式应用、一些不常用的库和类、或者是开发中经常被忽视的细节问题。这部分内容有助于完善学习者的知识体系,使其更加...

    61.拾遗增补-线程的状态.mp4

    在学习Java过程中,自己收集了很多的Java的学习资料,分享给大家,有需要的欢迎下载,希望对大家有用,一起学习,一起进步。

    java知识拾遗-三大框架的技术起源.docx

    Java开发中的三大框架——Struts、Hibernate和Spring,都是为了解决传统Java Web应用程序中存在的一系列问题而诞生的。这些框架分别针对MVC模式的实现、数据持久化和依赖管理给出了高效且灵活的解决方案。 Struts...

    10.java基础拾遗--匿名内部类的应用--实现scala中的集合map方法.mp4

    10.java基础拾遗--匿名内部类的应用--实现scala中的集合map方法.mp4

    11.java基础拾遗--匿名内部类语法详解.mp4

    11.java基础拾遗--匿名内部类语法详解.mp4

    读书笔记:算法 并发 函数式编程 java语言拾遗 手写设计模式.zip

    读书笔记:算法 并发 函数式编程 java语言拾遗 手写设计模式

    java知识拾遗-三大框架的技术起源.pdf

    Java开发中的三大框架,即Struts、Hibernate和Spring,各自解决了传统Java Web应用程序中的不同问题,提升了开发效率和代码质量。下面将详细讲解这三个框架的技术起源及其核心功能。 首先,Struts框架诞生于解决JSP...

    java8源码-new-Java:算法并发函数式编程java语言拾遗手写设计模式

    Java语言拾遗 │ │ └─util 工具类 │ └─mq 消息队列 │ └─kafka └─resources 消息队列源码会作专题研究 关于消息队列使用参考另一个库:https://github.com/GitJavaProgramming/springboot_mybatis 参考...

    Java JDK 6.0 学习笔记.pdf

    在学习过程中,参考官方文档、权威书籍和在线教程是必不可少的。例如《Thinking in Java》、《Java核心技术卷》以及Oracle的Java教程,都是深入理解Java的好资源。 通过系统地学习这些知识点,你将能够全面掌握Java...

    java面试进阶讲义

    - **数据结构**:`ArrayList` 基于动态数组实现,提供随机访问元素的能力,因此添加或删除元素时需要移动大量的元素。而 `LinkedList` 基于双向链表实现,对于插入和删除操作更加高效,因为只需要修改指针即可。 - *...

    洛中访袁拾遗不遇古诗阅读答案.docx

    《洛中访袁拾遗不遇》这首诗,不仅体现了孟浩然的文学艺术风格,还展示了他对于友人袁拾遗的深情厚谊,以及对其遭遇贬谪的同情。 首先,孟浩然在诗中通过“洛阳访才子”的句子,彰显了对袁拾遗才华的认可与尊敬。...

    17. 拾遗物品登记表.pdf

    17. 拾遗物品登记表.pdf

    超值个人java学习笔记

    在"day03 拾遗"中,特别提到了小数的取模运算。需要注意的是,Java中的小数取模与整数有所不同,可能会导致非预期的结果。例如,12.12%2.2的结果是1.1199,而8.8%2的结果是0。这是因为浮点数的取模运算并不总是精确...

    有感于《路边拾遗》-路边拾遗是什么意思.docx

    《路边拾遗》是一本由两位非职业摄影师创作的摄影画册,书中不仅收录了他们拍摄的精美照片,更重要的是传达了作者对摄影艺术的理解与感悟。通过这本画册,我们可以深刻理解摄影不仅仅是一种技术活动,更是一种心灵的...

    拾遗物品的处理.doc

    在中国传统文化中,拾金不昧被视为高尚的品德,而在现代社会,完善的拾遗物品管理制度则是社会主义精神文明建设的体现。本文将对拾遗物品的处理制度进行详细探讨,旨在为读者提供一个清晰的管理体系框架,以确保拾遗...

Global site tag (gtag.js) - Google Analytics