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();
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,122评论 6 505
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,070评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,491评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,636评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,676评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,541评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,292评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,211评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,655评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,846评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,965评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,684评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,295评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,894评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,012评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,126评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,914评论 2 355

推荐阅读更多精彩内容

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