一、概述

基于 fail-fast 机制,我们知道对于ArrayList等集合在迭代过程中是不可进行结构修改操作的,唯一能使用的结构修改操作只有Iterator接口中的remove()方法。
java.util.ListIterator接口继承自Iterator接口,是专用于列表集合的迭代器,在 Iterator 的基础上,额外提供了 previous、nextIndex、add、set 等方法。

next、previous语义上的小问题

  • 迭代器中的next()方法不应该理解为返回下一个元素,而是返回当前元素,并将指针移向下一个
  • cursor永远指向下一个待返回的元素下标。
  • previous() 则是将指针向前移动一个位置后返回元素。

比如以下情况:

    // 对于 List{3,4,5}ListIterator<Integer> listIterator = list.listIterator();boolean isDo = false; //isDo保证只向前移动一次,否则会死循环while(listIterator.hasNext()){Integer i = listIterator.next();if(i.equals(4)&&!isDo){i = listIterator.previous();isDo = true;}System.out.println(i);}

最后输出:

    34 //因为equal(4)时指针已经指向5了, previous会导致指针重回4//(而不是字面上想的当==4时,返回上一个3)45

修改对迭代过程是否可见?

是否可见具体看类(暂未找到对比)。如 对于ArrayList来说,迭代器并未使用副本数组,因此修改是可见的(但需要一定操作,因为add方法添加元素后会把指针再往后移一位【即,若一直next的话,等于忽略了迭代过程中添加的元素】)

二、一些类对LisIterator实现详解

2.1 ArrayList 对 ListIterator 的实现

对于ArrayList对ListIterator的实现来说,并不是取消了fail-fast机制,而是调用迭代器来修改的话,每次修改后都令expectedModCount = modCount,因此不会报ConcurrentModificationException异常。

源码如下:ListItrArrayList的内部类

    private class ListItr extends Itr implements ListIterator<E> {ListItr(int index) {super();cursor = index;  //构建是可指定迭代开始下标,默认是0}public boolean hasPrevious() { return cursor != 0; }/** 因为cursor始终指向下个元素下标 */public int nextIndex() { return cursor; }public int previousIndex() { return cursor - 1; }/** 返回cursor-1的元素 */@SuppressWarnings("unchecked")public E previous() {checkForComodification();int i = cursor - 1;if (i < 0)throw new NoSuchElementException();Object[] elementData = ArrayList.this.elementData;if (i >= elementData.length)throw new ConcurrentModificationException();cursor = i;return (E) elementData[lastRet = i];   //lastRet始终保存上次获取元素的下标}/** 省略set源码,set方法用以设置lastRet元素 *//** 添加方法*/public void add(E e) {checkForComodification();try {int i = cursor;ArrayList.this.add(i, e); //将元素添加在当前元素后面,也就是cursor的位置cursor = i + 1; //再将cursor+1,等于忽略刚添加的元素lastRet = -1;expectedModCount = modCount;} catch (IndexOutOfBoundsException ex) {throw new ConcurrentModificationException();}}}

2.2 CopyOnWriteArrayList 对ListIterator的实现

对于CopyOnWriteArrayList,虽然有lisIterator方法,但实则不支持列表迭代器的结构修改方法,如add、remove等(直接抛UnsupportedOperationException),因为它 fail-safe机制本身就支持迭代过程中去修改集合。但修改是不可见的,具体参考CopyOnWriteArrayList对fail-safe实现

转载于:https://www.cnblogs.com/simpleito/p/10902148.html

Java ListIterator 与 Iterator 异同相关推荐

  1. JAVA中ListIterator和Iterator详解与辨析

    在使用java集合的时候,都需要使用Iterator.但是java集合中还有一个迭代器ListIterator, 在使用List.ArrayList.LinkedList和Vector的时候可以使用. ...

  2. java iter是否存在_Java中ListIterator和Iterator的区别以及ListIterator的应用

    Java中ListIterator和Iterator详解与辨析 在使用java集合的时候,都需要使用Iterator.但是java集合中还有一个迭代器ListIterator,在使用List.Arra ...

  3. Java学习之Iterator(迭代器)的一般用法

    迭代器(Iterator) 迭代器是一种设计模式,它是一个对象,它可以遍历并选择序列中的对象,而开发人员不需要了解该序列的底层结构.迭代器通常被称为"轻量级"对象,因为创建它的代价 ...

  4. Java学习之Iterator(迭代器)的一般用法(转)

    迭代器(Iterator) 迭代器是一种设计模式,它是一个对象,它可以遍历并选择序列中的对象,而开发人员不需要了解该序列的底层结构.迭代器通常被称为"轻量级"对象,因为创建它的代价 ...

  5. Java中的Iterator(迭代器)

    Java中的Iterator(迭代器) 1 概述 ​ Java Iterator不是一个集合,是一种用于访问集合的方法,可用于迭代ArrayList和HashSet等集合.Iterator是Java迭 ...

  6. java set iterator_Java中的TreeSet的iterator()方法 Java.util.TreeSet.iterator() - Break易站

    Java中的TreeSet Java.util.TreeSet.iterator()方法用于返回与TreeSet相同元素的迭代器.元素以随机顺序从树集中的内容返回. 句法: Iterator iter ...

  7. java iterator_Java ArrayDeque iterator()方法与示例

    java iterator ArrayDeque类iterator()方法 (ArrayDeque Class iterator() method) iterator() Method is avai ...

  8. Java中set.iterator()的用法;

    java.util.Set.iterator() 方法用于返回与集合相同元素的迭代器.元素从集合中的内容以随机顺序返回. 句法 iterate_value = Set.iterator(); 参数:该 ...

  9. java迭代器(Iterator)

    一.前言 在迭代器(Iterator)没有出现之前,如果要遍历数组和集合,需要使用方法. 数组遍历,代码如下: String[] arr = new String[]{"Java" ...

  10. Java迭代器(Iterator)的用法

    Java迭代器(Iterator)的用法 什么是Iterator Iterator的应用 什么是Iterator Iterator(迭代器),它是一种用于访问集合的方法,可用于迭代 ArrayList ...

最新文章

  1. 高德技术评测建设之路
  2. Python_note6 组合数据类型+jieba库+文本词频统计
  3. 大型网站演化发展历程之二
  4. cat查看tomcat日志 linux_linux怎么使用cat命令查看文件? linux中cat命令的使用方法
  5. 发帖回帖功能 java_百度贴吧发贴回贴POST接口
  6. 数据库 | MySQL安装与配置
  7. win7下安装linux(CentOS)过程中遇到的问题总结
  8. 字典推导式_Python基础-推导式
  9. 关闭窗口(window.close)
  10. fatal error: torch/extension.h: No such file or directory
  11. 斯坦福与苹果基于Apple Watch检测心率异常,0.5%人群被检出,其中84%患有房颤...
  12. 记录红米k40解BL、Root、装XPOSED
  13. 杭州电子科技大学计算机专业考研分数线,2019杭州电子科技大学研究生分数线汇总(含2016-2019历年复试)...
  14. CPE/CPA/CPL/CPC/CPM/CPO/CPS/CPV/CPT/CPP广告
  15. 关于PyQt5 菜单点击实现打开chm格式的文件
  16. 水下光通信实现(1)----LED驱动电路
  17. Linux计算时间间隔
  18. 华为虚拟服务器忘记密码,远程服务器的密码忘记了
  19. 一种特定场景去除高光算法
  20. python飞机大战联网版_Python实现飞机大战(搞怪)游戏!这是你没见过的全新版本!...

热门文章

  1. 11.正则返回不是组的内容
  2. libgdx学习记录5——演员Actor
  3. 三种常用的js数组去重方法
  4. Ural 1043 Cover the Arc
  5. 类__slots__与__dict__用法
  6. [转载]EXT核心API详解Ext.data(八)- Connection/Ajax/Record javascript
  7. js怎样递归遍历树形菜单数据
  8. vxp grandle 自动更新应用
  9. 使用timerfd实现定时器功能
  10. 基于Jupyter完成Iris数据集的 Fisher线性分类,学习数据可视化技术