Java当中的Iterable 和Iterator

66 阅读3分钟

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才能支持这种等价过程。 [61B SP24] Lecture 11 - Inheritance 4_ Iterators, Object Methods(副本).jpg

Iterator抽象

上层的Iterable抽象需要下层的Iterator抽象来实现,也即是说该类内部需要提供一个Iterator类支持hasNext和next方法,那么针对该类设计一个继承自Iterator的类,在该类当中针对该类存储数据的物理结构实现SpecificIterator的hasNext和next方法即可 IterateDemo.gif

实例分析

这里以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

欢迎一起进步!