Java Iterable 与 Iterator

如果你想写一个foreach方法,访问List里面的所有对象,你可能会这么写

public static void forEach(List list) {
        int size = list.size();
        for(int i = 0; i < size; i++) {
            out.println(list.get(i));
        }
    }

但实际中,我们不需要这么麻烦,因为所有collection都有一个iterator()方法,在JDK1.4之前这个方法定义在collection接口中的,因此所有collection都有这个方法。

iterator()方法會傳回java.util.Iterator介面的實作物件,這個物件包括了Collection收集的所有物件,你可以使用Iterator的hasNext()看看有無下一個物件,若有的話,再使用next()取得下一個物件。因此,無論是List、Set、Queue或任何Collection,都可以使用以下的forEach()來顯示所收集之物件:

iterator方法会传回java.util.Iterator接口的实例对象,你可以使用hasNext方法看看有没有下一个对象,如果有的话,在使用next取得下一个对象,所以无论通过多态,无论是List,Set,Queue或者任何collection,都可以使用下面这个foreach方法收集对象:

public static void forEach(Collection collection) {
        Iterator iterator = collection.iterator();
        while(iterator.hasNext()) {
            out.println(iterator.next());
        }
    }

在JDK5之後,原先定義在Collection中的iterator()方法,提昇至新的java.util.Iterable父介面,因此在JDK5之後,你可以使用以下的forEach()方法顯示收集的所有物件:
在JDK5之后,原先定义在collection中的iterator方法,提升到新的java.util.Iterable接口中,这样做的好处是,所有实现了iterable接口的对象,都是可迭代的,而之前只有collection是可迭代的。所以在JDK5之后,可以使用下面的foreach方法收集所有的对象:

public static void forEach(Iterable iterable) {
        Iterator iterator = iterable.iterator();
        while(iterator.hasNext()) {
            out.println(iterator.next());
        }
    }

同时由于JDk5之后还引入了增强式的for循环,foreach可以进一步的简化

import java.util.*;

public class ForEach {
    public static void main(String[] args) {
        List names = Arrays.asList("Justin", "Monica", "Irene");
        forEach(names);
        forEach(new HashSet(names)); 
        forEach(new ArrayDeque(names)); 
    }

    public static void forEach(Iterable iterable) {
        for(Object o : iterable) {
            System.out.println(o);
        }
    }
}

实际上,增强式for循环是编译器的蜜糖,实际代码会展开为:

public static void forEach(Iterable iterable) {
    Object o;
    for(Iterator i\$ = iterable.iterator(); i\$.hasNext(); System.out.println(o)) {
        o = i\$.next();
    }
}

可以看到实际还是调用iterator方法。

由于iterable接口的引进,导致所有实现了这个接口的方法,都可以iterator,看下面这个例子:

package Collection;

import java.util.Iterator;

public class IterableString implements Iterable<Character> {
    
    private String original;

    public IterableString(String original) {
        this.original = original;
    }

    public static void main(String[] args) {
        IterableString str = new IterableString("Justin");
        for(Character c : str) {
            System.out.println(c);
        }
        // TODO Auto-generated method stub

    }

    @Override
    public Iterator<Character> iterator() {
        // TODO Auto-generated method stub
        return new InnerIterator();
    }
    
    private class InnerIterator implements Iterator<Character> {
        private int index;
        public boolean hasNext() {
            return index < original.length();
        }

        public Character next() {
            Character c = original.charAt(index);
            index++;
            return c;
        }

        public void remove() {}
    }

}

查看编译器,我们发现编译器做了这些事:

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

推荐阅读更多精彩内容

  • 接口/抽象类意义规范、扩展、回调为其子类提供一个公共的类型 封装子类中得重复内容 定义抽象方法,子类虽然有不同的实...
    MigrationUK阅读 2,212评论 1 28
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,805评论 18 399
  • 对象的创建与销毁 Item 1: 使用static工厂方法,而不是构造函数创建对象:仅仅是创建对象的方法,并非Fa...
    孙小磊阅读 2,046评论 0 3
  • Java 集合类是一种特别有用的工具类,大致可分为Set、List、Queue、Map四种体系。 Set代表无序、...
    ifeelok0319阅读 308评论 0 0
  • 很多时候不想新建一个文件去实现一些很小的功能 想在浏览器中直接改变当前浏览页面的样式或者获取一些内容 1.在ch...
    田永威阅读 384评论 0 0