java集合系列05 Iterable Iterator ListIterator
来源:互联网 发布:php 清空文件 编辑:程序博客网 时间:2024/06/05 16:52
费话不多说,还是先上uml图
Java集合框架中绝大多数的类都间接或直接的实现并依赖于Iterable
Iterable
文档介绍
实现此接口允许此类的实例成为for-each循环语句的目标
源码
public interface Iterable<T>{ //返回一个迭代器,可遍历整个集合元素 Iterator<T> iterator();}
Iterator
文档介绍
一个遍历整个集合迭代器,Iterator替换了Java集合框架的Enumeration类,迭代器与枚举有两点不同:
- 迭代器在迭代集合期间可以删除集合的元素
- 方法全名更加精简
源码
public iterface Iterator<E>{ //判断集合是否有下一个元素 boolean hasNext(); //返回集合的下一个元素 E next(); //删除next()返回的元素, //每调用一次next()方法只能调用一次remove()方法 //如果在迭代集合期间,调用了此方法这外的其他方式修改了该迭代器所指向的collection,则迭代器的行为是不确定的 default void remove(){ throw new UnsupportedOperationException("remove"); }
ListIterator
文档介绍
列表迭代器,允许程序员按任意方向遍历列表、迭代期间修改列表,并获得迭代器在列表中的当前位置。ListIterator没有当前元素;它的光标位置始终位于调用previous()所返回的元素和调用next()所返回的元素之间。
源码
public iterface ListIterator<E> extends Iterator<E>{ boolean hasNext(); E Next(); boolean hasPrevious(); E previous(); int nextIndex(); int prevouseIndex(); //修改操作 //删除next()或previous()方法最后返回的元素,此方法只能在每次调用next()或previouse()方法之后并且没有调用add方法时使用 void remove(); //修改next()或previous()方法最后返回的元素,此方法只能在 //每次调用next()或previouse()方法,并且没有调用remove()或add()方法时使用 void set(E e); //将指定的元素插入列表(可选操作)。该元素直接插入到 next 返回的下一个元素的前面(如果有),或者 previous 返回的下一个元素之前(如果有);如果列表没有元素,那么新元素就成为列表中的唯一元素。新元素被插入到隐式光标前:不影响对 next 的后续调用,并且对 previous 的后续调用会返回此新元素(此调用把调用 nextIndex 或 previousIndex 所返回的值增加 1)。 void add(E e);
我研究到这的时候,虽然明白怎么使用,但是对其源码还不了解,所以等到讲解ArrayList的源码时,再详细说明吧。
也许下面这张图可以说清ListIterator()的使用原理
^Element(0) ^ Element(1) ^ Element(2) ^ … ^Element(n-1)^
^代表指针 remove()会删除指针后面的一个元素,add()会在当前指针插入元素,
previous()返回当前指定的前一个元素,next()返回当前指定的后一个元素,previousIndex()返回要返回前一个元素的索引,nextIndex()返回要返回的下一个元素的索引
AbstractList里关于Iterator 和 ListIterator的具体实现
public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E>{...private class Itr implements Iterator<E>{ //后续调用next方法返回元素的索引 int cursor = 0; //最近调用next或previous方法返回元素的索引 //如果元素被调用方法remove删除,lastRet被重置为-1 //lastRet 是 lastReturn的简写 int lastRet = -1; //期待的元素数量,如果此变量的值与数组的元素的数量不一致,则在迭代期间发生了并发的添加或删除 int expectedModCount = modCount; //检测是否并发的添加或删除 final void checkForComodificaton(){ if(modCount != expectedModCount){ throw new ConcurrentModificationException(); } } //如果指针不等于List的元素数量,说明有下一个 public boolean hasNext(){ return cursor != size(); } //返回当前指针所代表的元素 //此方法采用了checkForComodificaton(), 捕获数组越界异常来检测数组并发删除或添加元素 public E next(){ checkForComodificaton(); try{ int i = cursor; E next = get(i); //获取元素 lasRet = i; //相当于+1 cursor = i + 1; //相当于+1 return next; }catch(IndexOutOfBoundsException e){ //如果cursor越界,抛出NoSuchElementException checkForComodificaton(); throw new NoSuchElementException(); }
public void remove(){ if(lastRet < 0){ throw new IllegalStateException(): } checkForComodificaton(); try{ AbstractList.this.remove(lastRet); if(lastRet < cursor){//判断上次调用是next(lastRet < cursor) 还是 previous(lastRet == cursor) cursor--; //因为删除list当前指针的前一个元素,所以cursor要 -1以正确的指向下一个元素的位置 } lastRet = -1; //重置为-1 expectedModCount = modCount; }catch(IndexOutOfBoundsException e){ throw new ConcurrentModificationException(); } }
private class ListItr extends Itr implements ListIterator<E>{ //构造器 支持指定索引 ListItr(int index) { cursor = index; }
返回指针的前一个元素
并把lastRet 和 cursor设置为 cursor-1
如果cursor-1小于0捕获IndexOutOfBoundsException 并抛出 NoSuchElementException
public E previous(){ checkForComodificaton(); try{ int i = cursor - 1; E previous = get(i); lastRet = cursor = i; return previous; }catch(IndexOutOfBoundsException e){ checkForComodificaton(); throw new NoSuchElementException(); } }
两个简单的返回下一个元素或上一个元素的方法
public int nextIndex(){ return cursor; } public int previouseIndex(){ return cursor - 1; }
此set方法以lastRet为中心
设置lastRet指向的元素(可以多次重复设置)
public void set(E e) { if (lastRet < 0) throw new IllegalStateException(); checkForComodification(); try { AbstractList.this.set(lastRet, e); expectedModCount = modCount; } catch (IndexOutOfBoundsException ex) { throw new ConcurrentModificationException(); } }
此add方法以cursor为中心的方法
调用完add方法重置lastRet,所以不能调用remove, set方法了
//添加操作 //在当前指针处添加元素,当前指针向后移一位,lastRet重置为-1,重新设置expectedModCount public void add(E e) { checkForComodification(); try { int i = cursor; AbstractList.this.add(i, e); //调用List自身的add方法添加元素 lastRet = -1; //重置lastRet cursor = i + 1; //指针加1 expectedModCount = modCount; //重新设置expectedModCount } catch (IndexOutOfBoundsException ex) { throw new ConcurrentModificationException(); } } }}
- java集合系列05 Iterable Iterator ListIterator
- Iterator、listIterator、Iterable
- JDK学习之集合包—Iterator、ListIterator、Iterable
- [JAVA] 集合类增删改,Iterator, ListIterator
- java集合----Iterable和Iterator的区别
- Java Iterator与ListIterator
- java:Iterator和ListIterator
- 【java】Enumeration、Iterator、ListIterator
- Java Iterable、Iterator、iterator区别
- Iterable Iterator Java
- Java Collection Iterable Iterator
- java 1.8 集合源码解析1:Iterable和Iterator
- 集合2 Iterator迭代器 ListIterator
- java(18)------Iterator和ListIterator
- Java中的Iterable和Iterator
- java.util Iterable and Iterator
- Java迭代器---Iterable和Iterator
- Java Iterable 和 Iterator 示例
- 虚拟机修改ip地址和主机名
- get和post的区别--面试经常被问到!(一)
- Struts2的Hello Word
- java集合系列06 AbstractList
- Binary Watch
- java集合系列05 Iterable Iterator ListIterator
- 【论文阅读】SSD: Single Shot MultiBox Detector
- [Android]service list与dumpsys -l的结果差异分析
- 关于盒子制作的表格的双边框问题
- Linux常用命令学习
- 显示错误信息
- VS2010 CUDA8.0 工程配置
- 字符编码笔记:ASCII,Unicode和UTF-8
- 6. ZigZag Conversion