ListIterator

根据官方文档介绍, ListIterator 有以下功能:

  1. 允许我们向前、向后两个方向遍历 List;
  2. 在遍历时修改 List 的元素;
  3. 遍历时获取迭代器当前游标所在位置。

注意,迭代器 没有当前所在元素一说,它只有一个游标( cursor )的概念,这个游标总是在元素之间,比如这样:

初始时它在第 0 个元素之前,调用 next() 游标后移一位:

调用 previous() 游标就会回到之前位置。当向后遍历完元素,游标就会在元素 N 的后面:

也就是说长度为 N 的集合会有 N+1 个游标的位置。


ListIterator 继承自 Iterator 接口(关于 Iterator 的介绍 请点这里),在 Iterator 的基础上增加了 6 个方法:

介绍一下新来的几个方法:

  • void hasPrevious()

    • 判断游标前面是否有元素;
  • Object previous() 
    • 返回游标前面的元素,同时游标前移一位。游标前没有元素就报 java.util.NoSuchElementException 的错,所以使用前最好判断一下;
  • int nextIndex() 
    • 返回游标后边元素的索引位置,初始为 0 ;遍历 N 个元素结束时为 N;
  • int previousIndex() 
    • 返回游标前面元素的位置,初始时为 -1,同时报 java.util.NoSuchElementException 错;
  • void add(E) 
    • 在游标 前面 插入一个元素
    • 注意,是前面
  • void set(E) 
    • 更新迭代器最后一次操作的元素为 E,也就是更新最后一次调用 next() 或者 previous() 返回的元素。
    • 注意,当没有迭代,也就是没有调用 next() 或者 previous() 直接调用 set 时会报 java.lang.IllegalStateException 错;
  • void remove() 
    • 删除迭代器最后一次操作的元素,注意事项和 set 一样。

ListIterator 有两种获取方式

  • List.listIterator()
  • List.listIterator(int location)

区别在于第二种可以指定 游标的所在位置。

ListIterator 的具体实现?

AbstractList 作为 List 的直接子类,里面实现了 listIterator() 方法,并且有两个内部迭代器实现类:SimpleListIterator,FullListIterator:

listIterator() 返回的是 FullListIterator():

FullListIterator 继承了 SimpleListIterator, SimpleListIterator 实现了 Iterator 接口:

private class SimpleListIterator implements Iterator<E> {//游标的位置,初始为 -1int pos = -1;//用来判断是否 fail-fast 的变量int expectedModCount;//记录上次迭代的位置int lastPosition = -1;SimpleListIterator() {expectedModCount = modCount;}//当游标没有跑到最后一个元素后面时 hasNext 返回 truepublic boolean hasNext() {return pos + 1 < size();}//获取下一个元素public E next() {if (expectedModCount == modCount) {try {//获取游标后面的元素,具体子类有具体实现E result = get(pos + 1);//更新lastPosition = ++pos;return result;} catch (IndexOutOfBoundsException e) {throw new NoSuchElementException();}}//当迭代时修改元素,就会报这个错,上篇文章介绍过解决办法~throw new ConcurrentModificationException();}//删除上次迭代操作的元素public void remove() {//还没进行迭代操作就会报这个错if (this.lastPosition == -1) {throw new IllegalStateException();}if (expectedModCount != modCount) {throw new ConcurrentModificationException();}try {//调用子类实现的删除操作AbstractList.this.remove(lastPosition);} catch (IndexOutOfBoundsException e) {throw new ConcurrentModificationException();}expectedModCount = modCount;if (pos == lastPosition) {pos--;}//每次删除后都会还原为 -1,也就是说我们迭代一次后只能 remove 一次,再 remove 就会报错lastPosition = -1;}
}

了解了 SimpleListIterator 后我们看下 FullListIterator 的具体实现:

private final class FullListIterator extends SimpleListIterator implements ListIterator<E> {//根据 start 指定游标位置FullListIterator(int start) {if (start >= 0 && start <= size()) {pos = start - 1;} else {throw new IndexOutOfBoundsException();}}//在游标前面添加元素public void add(E object) {if (expectedModCount == modCount) {try {//调用子类的添加操作,ArrayList, LinkedList,Vector 的添加操作实现有所不同AbstractList.this.add(pos + 1, object);} catch (IndexOutOfBoundsException e) {throw new NoSuchElementException();}//游标后移一位pos++;//!注意! 添加后 上次迭代位置又变回 -1 了,说明 add 后调用 remove, set 会有问题!lastPosition = -1;if (modCount != expectedModCount) {expectedModCount = modCount;}} else {throw new ConcurrentModificationException();}}//当游标不在初始位置(-1)时返回truepublic boolean hasPrevious() {return pos >= 0;}//游标后面的元素索引,就是游标 +1public int nextIndex() {return pos + 1;}//游标前面一个元素public E previous() {if (expectedModCount == modCount) {try {E result = get(pos);lastPosition = pos;pos--;return result;} catch (IndexOutOfBoundsException e) {throw new NoSuchElementException();}}throw new ConcurrentModificationException();}//游标前面元素的索引,就是游标的位置,有点晕的看开头那几张图public int previousIndex() {return pos;}//更新之前迭代的元素为 objectpublic void set(E object) {if (expectedModCount == modCount) {try {//调用子类的setAbstractList.this.set(lastPosition, object);} catch (IndexOutOfBoundsException e) {throw new IllegalStateException();}} else {throw new ConcurrentModificationException();}}
}

可以看到 SimpleListIterator 的主要操作最后都交给子类来实现,List 的子类 ArrayList, LinkedList, Vector 由于底层实现原理不同(数组,双向链表),具体操作类实现有所不同。

ListIterator相关推荐

  1. Java 集合系列(四)—— ListIterator 源码分析

    以脑图的形式来展示Java集合知识,让零碎知识点形成体系 Iterator 对比   Iterator(迭代器)是一种设计模式,是一个对象,用于遍历集合中的所有元素.   Iterator 包含四个方 ...

  2. ListIterator特有的方法

    import java.util.ArrayList; import java.util.List; import java.util.ListIterator;/* 迭代listIterator() ...

  3. java迭代器在哪个包里面,java.util.LinkedList.listIterator()方法实例

    全屏 java.util.LinkedList.listIterator(int index)方法返回一个列表迭代器在此列表中的元素(按适当顺序),从列表中的指定位置. 声明 以下是java.util ...

  4. java iterator 将int_ListIteratorlt;Egt; listIterator(int index)_Java.util包|WIKI教程

    ListIterator listIterator(int index) 描述 (Description) java.util.LinkedList.listIterator(int index)方法 ...

  5. Iterator 和 ListIterator 有什么区别?

    1.ListIterator 可以在遍历的时候,调用add()添加元素 2.ListIterator提供了更多的一些方法,如previous().hasPrevious() 等 转载于:https:/ ...

  6. Java迭代器ListIterator

    ListIterator Iterator的子类,增加了一些特有的方法 用于遍历集合中的元素 可以正向迭代.反向迭代 正向迭代,从第一个元素,到最后一个元素 反向迭代,从最后一个元素,到第一个元素 I ...

  7. 列表迭代器ListIterator的用法

    ListIterator的父接口是Iterator,是List接口中特有的迭代器. ListIterator在Iterator的基础上,又新添了很多方法: Iterator中的方法: 1.判断是否有下 ...

  8. Iterator和ListIterator接口的使用和区别

    1.Iterator接口 1.1.Iterator接口概述 java.util.Iterator 接口提供遍历任何 Collection 的接口.我们可以从一个 Collection 中使用迭代器方法 ...

  9. Java14-day05【集合(Collection常用方法-遍历、List特有方法、List集合子类特点、LinkedList集合的特有功能、ListIterator)】

    视频+资料(工程源码.笔记)[链接:https://pan.baidu.com/s/1MdFNUADVSFf-lVw3SJRvtg   提取码:zjxs] Java基础--学习笔记(零起点打开java ...

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

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

最新文章

  1. 软件设计中的具体问题
  2. mysql 多表查询练习题_mysql多表查询练习
  3. Linux系统的中断、系统调用和调度概述【转】
  4. 青岛经济职业学校计算机老师,青岛经济职业学校2021年录取分数线
  5. 文件从一台服务器拷贝到另一台服务器
  6. 千头万绪:从一道面试题看数据库性能和安全的方方面面
  7. python基础快速入门day01
  8. flash cs4 是过渡性产品吗?
  9. EXCEL VBA编程入门二:什么是VBA?什么是EXCEL VBA?
  10. SPSS可信度数据分析
  11. 大数据前端个人提升与团队规划
  12. 使用超临界二氧化碳的晶圆清洗技术
  13. 用户画像设计与搭建(附金融行业用户画像案例)
  14. 一个关于springboot的junit使用错误,空指针异常
  15. .Net Micro Framework 嵌入式开发
  16. [Audacity][帮助手册][手册内容]认识Audacity
  17. 卫星定位原理以及室内定位技术
  18. Mathematics English Vocabulary (Cited)
  19. 王姨劝我学HarmonyOS鸿蒙2.0系列教程之二应用知识梳理逻辑!
  20. 计算机录音机应用程序在哪,win10电脑自带录音在哪里打开

热门文章

  1. 初学者C语言练习题-指针
  2. 主流Web架构相互比较
  3. Penetration_Testing_POC-About 渗透测试有关的POC、EXP、脚本、提权、小工具等
  4. 22款奔驰C260L升级原厂360全景影像 倒车更加直观
  5. autocad型源代码_VB与AUTOCAD二次开发源代码包
  6. 如何比较好的规避拼多多纠纷退款的技巧?天创速盈来说
  7. 频上“热搜”的人工智能专业,主要学什么?为什么如此火爆?
  8. 图像的几何变换—平移、旋转、镜像、缩放、剪切(原理+调用函数+像素操作)
  9. 【技术人快报】摩拜单车多地区现Bug+iCloud完成中国本土化落地
  10. [转]ModSecurity for Apache 1.8.7 用户手册