Java中Iterable和Iterator接口

接口定义

public interface Iterable<T> {
  Iterator<T> iterator();
}

public interface Iterator<E> {
  boolean hasNext();
  E next();
  void remove();
}

Iterable只是返回了Iterator接口的一个实例,这里很是奇怪,为什么不把两个接口合二为一,直接在Iterable里面定义hasNext(),next()等方法呢?

原因是实现了Iterable的类可以在实现多个Iterator内部类,例如LinkedList中的ListItrDescendingIterator两个内部类,就分别实现了双向遍历和逆序遍历。通过返回不同的Iterator实现不同的遍历方式,这样更加灵活。如果把两个接口合并,就没法返回不同的Iterator实现类了。

上个代码,直观地展示一下实现了Iterable的类如何通过返回不同的Iterator从而实现不同的遍历方式。MutilIterator实现了三种迭代器,分别是默认的前向迭代器,反向迭代器和随机迭代器。主函数中分别调用了三种迭代器进行遍历。

代码示例

MutilIterator.java

import java.util.*;

public class MutilIterator implements Iterable<String> {
 private String[] words = "May I get offers this summer.".split(" ");

    //默认的迭代器,前向遍历
    public Iterator<String> iterator() {
       //匿名内部类
        return new Iterator<String>() {
            private int index = 0;
            public boolean hasNext() {return index < words.length;}
            public String next() { return words[index++];    }
            public void remove() { // Not implemented
                throw new UnsupportedOperationException();
            }
        };
    }

//反向迭代器
    public Iterable<String> reverseIterator() {
        return new Iterable<String>() {
            @Override
            public Iterator<String> iterator() {
                return new Iterator<String>() {
                    private int index = words.length - 1;
                    public boolean hasNext() {return index > -1; }
                    public String next() {return words[index--]; }
                    public void remove() { // Not implemented
                        throw new UnsupportedOperationException();
                    }
                };
            }
        };
    }
//随机迭代器,注意这里不是创建一个新的Iterator,而是返回了一个打乱的List中的迭代器
    public Iterable<String> randomized() {
        return new Iterable<String>() {
            public Iterator<String> iterator() {
                List<String> shuffled = new ArrayList<>(Arrays.asList(words));
                Collections.shuffle(shuffled, new Random(47));
                return shuffled.iterator();
            }
        };
    }
public static void main(String[] args) {
        MutilIterator mi = new MutilIterator();
       //默认的迭代器
        for (String String : mi) {
            System.out.print(String + " ");
        }
        System.out.println();
       //反向迭代器
        for (String String : mi.reverseIterator()) {
            System.out.print(String + " ");
        }
        System.out.println();
        //随机迭代器
        for (String String : mi.randomized()) {
            System.out.print(String + " ");
        }
    }/*Output:
  May I get offers this summer. 
  summer. this offers get I May 
  I this offers summer. May get 
*///

结论:

Java容器中,所有的Collection子类会实现Iteratable接口以实现foreach功能,Iteratable接口的实现又依赖于实现了Iterator的内部类(参照LinkedListlistIterator()descendingIterator()的JDK源码)。有的容器类会有多个实现Iterator接口的内部类,通过返回不同的迭代器实现不同的迭代方式。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 1 场景问题# 1.1 工资表数据的整合## 考虑这样一个实际应用:整合工资表数据。 这个项目的背景是这样的,项目...
    七寸知架构阅读 2,577评论 0 53
  • 接口/抽象类意义规范、扩展、回调为其子类提供一个公共的类型 封装子类中得重复内容 定义抽象方法,子类虽然有不同的实...
    MigrationUK阅读 2,187评论 1 28
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,742评论 18 399
  • 《世法哲言》(三十三) 大树之材顶立于天地日月,受风寒暑湿之侵而成焉,故藏室植树纵立屋顶,亦黄胎萌芽而已。设若人者...
    柏小林阅读 422评论 0 1
  • 开始喝牧做的蜂蜜柠檬。 半年前嗓子不好用了,喝柠檬水,喝薄荷叶。薄荷,天呐,好凉快,就像嗓子眼装了一个小风扇。喝的...
    触角_阅读 222评论 0 1