preview
众所周知,java是完全面向对象的语言,其核心便是一切设计都是为了对象,一切设计也即是对象,iterable和iterator也不例外。在上cs61B的课程时,什么是迭代器,为什么要有迭代器对象,iterator方法是干什么用的,为什么要继承iterable类,为什么要在类内单独再写一个类去实现itetor类等等诸多问题困扰着我。
原理解析
两层抽象
但是如果从对象的角度来看,我们需要一个interface去从简单的code到for-each loop的转换,这个interface就是iterable,他将我们背后调用的过程封装成for-each loop。那么背地里去实现这个简单code的幕后黑手是谁?是一个Iterator对象,但是这个对象是和当前类所绑定的,因此需要针对这个类单独设计一个Iterator类用来处理与这个类相关的数据,我们们姑且称这个Iteartor类为SpecificIterator。
明白了这两点之后我们可以理解,中间有两层抽象过程,第一层是从单纯的遍历到SpecificIterator的抽象,即Iterator的抽象,这个抽象使得我们遍历类的数据时脱离了类的具体实现,反而用迭代器的方法泛化了我们遍历的过程。第二层是迭代器到for-each loop的抽象,即Iterable的抽象,这里我们稍后会结合两份代码来讲述
Iterable抽象
Iterable抽象指的是,左边的for-each loop实际上等价于右边较为丑陋简单的代码,而这个等价过程就是通过Iterable抽象而来的,只有声明了Iterable才能支持这种等价过程。
Iterator抽象
上层的Iterable抽象需要下层的Iterator抽象来实现,也即是说该类内部需要提供一个Iterator类支持hasNext和next方法,那么针对该类设计一个继承自Iterator的类,在该类当中针对该类存储数据的物理结构实现SpecificIterator的hasNext和next方法即可
实例分析
这里以Deque61B为例
如果有类LinkedListDeque61B,该类的部分定义和类内方法的实现如下
public class LinkedListDeque61B<T> implements Deque61B<T>,Iterable<T>
{
// data storage: bidirectional node
private class LNode {
public LNode prev;
public T item;
public LNode next;
LNode(T i, LNode n) {
item = i;
next = n;
// n.prev=this;
}
private LNode sentFront;
private LNode sentBack;
private int size_;
private class SpecificIterator implements Iterator<T>
{
private LNode wizPos ;
SpecificIterator()
{
wizPos=sentFront.next;
}
/**
* Returns {@code true} if the iteration has more elements.
* (In other words, returns {@code true} if {@link #next} would
* return an element rather than throwing an exception.)
*
* @return {@code true} if the iteration has more elements
*/
@Override
public boolean hasNext() {
return wizPos!=sentBack;
}
/**
* Returns the next element in the iteration.
*
* @return the next element in the iteration
* @throws NoSuchElementException if the iteration has no more elements
*/
@Override
public T next() {
T returnItem =wizPos.item;
wizPos=wizPos.next;
return returnItem;
}
}
/**
* Returns an iterator over elements of type {@code T}.
*
* @return an Iterator.
*/
@Override
public Iterator<T> iterator() {
return new SpecificIterator();
}
}
该类继承Iterable,在类内实现iteartor方法并且返回一个Iterator对象。类内定义SpecificIterator,实现hasNext和next方法。
收获与感悟
感觉java当中的迭代器和C++的迭代器不太一样,C++的迭代器是针对容器而设计的,java的迭代器是面对对象而设计的,还没有设计过C++的迭代器。
写在后面
欢迎指出错误!
欢迎交流联系2310460@mail.nankai.edu.cn
欢迎关注我的 github
欢迎一起进步!