[toc]html
前文传送门:Enumeration 上一篇,咱们谈到了那个古老的迭代器Enumeration,还谈到了取代他的新迭代器——Iterator。相比于以往,这个新物种又有哪些优势呢?java
迭代器这个词,在没查找许多资料以前,我只知道个大概,我知道它能够用来遍历集合,可是至于它其中的奥妙,并无作深究。本篇文章关于Iterator迭代器作了小小的总结,巩固学习,若是有理解错误,或叙述不当之处,还望你们评论区批评指针。编程
官方文档对Iterator的解释是:设计模式
不行不行,这描述也太简略了,我继续查找资料:ide
- 迭代器自己是个对象,建立迭代器的代价很小,一般被称为轻量级对象。
- 迭代器其实也是一种设计模式,它提供了一种方法顺序访问一个聚合对象中的各个元素,但又不暴露该对象的内部表示。
针对以上种种,我充满了好奇,因而在复杂的继承关系里画了又画,最终才渐渐理清集合中所谓迭代器模式的体现,暂时以ArrayList为例: 学习
hasNext():boolean
判断下一个元素还有没有,有就是true。next(): E
返回序列中的下一个元素。经过查看源码,我发现,在这个Itr这个实现类中,定义了两个指针:cursor
和lastRet
。(还有个属性为expectedModCount初始化为ArrayList的版本号modCount,这部分与fail-fast机制相关,以后会再提)而cursor初始为0,与专门用来和集合元素数目size作比较的。而lastRet初始化为-1,若是成功执行next操做,将会加1变成0,也就是上面说的“下一个元素”可想而知,能够把lastRet认为是初始化为第一个元素以前的指针,和将要返回的值的索引相同,这样会好记一些。测试
除了上面两个方法,JDK1.8新增了两个方法,也是体现处它与老迭代器不一样的新优点:支持了删除操做。优化
remove():void
将新近返回的元素删除。 须要注意的是:remove方法没有新近返回的元素,也就是说lastRet<0,会抛出异常。若是移除成功,让cursor往回退一格,lastRet重置为-1。spa
forEachRemaining(Consumer<? super E> consumer):void
这个是JDK1.8中Iterator新增的默认方法:对剩余的元素执行指定的操做。 可能不太好理解:咱们经过测试来讲明一下:debug
List<Integer> list = new ArrayList<>(); list.add(1); list.add(2); list.add(3); //建立一个Iterator对象 Iterator<Integer> it = list.iterator(); //返回第一个值 System.out.print(it.next()+" ");
测试结果很明显,只输出了第一个元素:1。 咱们继续在原代码的基础上咱们的新方法:
it.forEachRemaining(new Consumer<Integer>() { @Override public void accept(Integer integer) { System.out.print(integer+" "); } });
测试结果为:1 2 3,在原来的基础上,把剩下的元素都打印了出来。而这个新增的方法,其实和咱们熟悉的这个是同样的:
while(it.hasNext()){ System.out.print(it.next()+" "); }
值得一提的是:咱们以前学习的加强for循环,在底层其实就是运用了Iterator,我经过IDE的debug调试功能,发如今调用运行到加强for循环时,自动调用了集合的iterator()方法,返回了一个Iterator的实现类实例。
经过对Iterator中定义方法的学习,咱们大概知道了迭代器的用途,就是从前向后一个一个遍历元素,而无视其内部结构。欸,遍历我都懂,可无视结构在哪里体现啊?别急,下面来看一个例子,让咱们无视两个不一样集合的结构:
首先咱们定义一个方法,它能够接收一个迭代器对象:
public static void display(Iterator<?> T){ while(T.hasNext()){ System.out.print(T.next()); } }
而后咱们建立两个不同的集合,一个是ArrayList,一个是HashSet,自己是无序的,咱们接下来应该会作相应的源码学习。
//ArrayList 有序 List<String> list = new LinkedList<>(); list.add("天"); list.add("乔"); list.add("巴"); list.add("夏"); //HashSet 无序 Set<Integer> set = new HashSet<>(); set.add(11); set.add(22); set.add(33); set.add(44); display(list.iterator());//天 乔 巴 夏 System.out.println(); display(set.iterator());//33 22 11 44
能够看出来,两个不一样集合的迭代器传入display方法以后,都能用一种相同的方式访问集合中的元素。 经过上面的一顿分析,咱们能够肯定,迭代器这玩意儿,统一了访问容器的方式。
最后,关于迭代器,还有一部份内容,在往后会作总结。 参考资料:《大话设计模式》、《Java编程思想》
原文出处:https://www.cnblogs.com/summerday152/p/12210030.html