新手上路學Java:兩分鐘讓你看懂Java迭代器的規則,使用方法,原理

概述

迭代器,提供了在不瞭解集合內部實現方法的時候遍歷集合的能力。可以將容器內部實現與遍歷操作隔離、解耦。

使用迭代器實現一個簡單集合

通過自定義一個簡單集合,並在對其使用迭代器進行遍歷,達到掌握迭代器的目的。

集合描述

一個簡單的集合,規則如下

  • 1、只能存放三個字符串
  • 2、若插入第四個數據,則覆蓋第一個位置。

實現接口描述

Iterable接口描述

  • 如果想用foreach對集合遍歷,則必須實現該接口。(具體原因在後面說明)
  • iterator():是必須實現的接口,返回了一個迭代器。

Iterator

  • 迭代器,可以對已知集合進行遍歷操作。
  • hasNext():必須實現,返回一個boolean表示是否有下一個值
  • next():必須實現,從集合中返回下一個元素。

代碼實現

自定義集合

/**
 * 自定義集合
 * 功能: 只能插入三個元素, 插入第四個元素會替換集合中第一個元素
 * 實現了Iterable(可迭代)接口,必須要實現其中的iterator方法,返回一個迭代器
 **/
public class MyCollection implements Iterable<String> {
    String value1;
    String value2;
    String value3;

    int currentValueIndex = 1;

    public String get(int index) {
        switch (index) {
            case 1: return value1;
            case 2: return value2;
            case 3: return value3;
            default: return null;
        }
    }

    /**
     * 添加一個元素, currentValueIndex爲當前元素索引, 表示下一次插入的位置
     * 維護了一個只可以插入三個String的集合
     * @param value
     * @return
     */
    public boolean add(String value) {
        switch (currentValueIndex) {
            case 1: value1 = value; currentValueIndex++; break;
            case 2: value2 = value; currentValueIndex++; break;
            case 3: value3 = value; currentValueIndex-=2; break;
            default: break;
        }
        return true;
    }

    /**
     * 返回我們自己定義的集合迭代器
     * @return
     */
    @Override
    public Iterator<String> iterator() {
        return new MyCollectionIterator(this);
    }
}

自定義迭代器

自定義了一個迭代器,可以對上面自定義集合進行遍歷。

/**
 * 給我自己實現的集合實現一個迭代器
 * 必須實現的方法
 * hasNext是否有下一個元素
 * next取出下一個元素
 */
public class MyCollectionIterator implements Iterator<String> {

    int index = 1;

    int maxIndex = 3;

    MyCollection myCollection;

    public MyCollectionIterator(MyCollection myCollection) {
        this.myCollection = myCollection;
    }

    /**
     * 如果當前指針已經指向3,就沒有下一個了,返回false
     * 否則還有下一個
     * @return
     */
    @Override
    public boolean hasNext() {
        if (index > maxIndex) {
            return false;
        }
        return true;
    }

    /**
     * 取出下一個元素,指針向前移動一步
     * @return
     */
    @Override
    public String next() {
        String result = myCollection.get(index);
        index ++;
        return result;
    }

}

測試方法

public class Test {
    public static void main(String[] args) {
        MyCollection collection = new MyCollection();
        collection.add("test1");
        collection.add("test2");
        collection.add("test3");

        /**
         * 循環1,獲取MyCollection的迭代器, 用while和next、hasNext遍歷我們的自定義集合
         */
        Iterator<String> iterator = collection.iterator();
        while (iterator.hasNext()) {
            String str = iterator.next();
            System.out.println(str);
        }


        /**
         * 循環2,因爲我們的集合實現了Iterable接口,因此可以使用forEach循環
         * 但是foreach循環編譯的結果是和循環1一模一樣的代碼
         */
        for (String s : collection) {
            System.out.println(s);
        }
    }
}

測試代碼反編譯結果

這裏是上述測試代碼反編譯後的代碼,可以看到,上面的循環2(foreach),已經被編譯成了和循環1一樣的結構。這裏可以看出,foreach循環最終其實是會使用iterator()方法獲取迭代器,來完成遍歷。因此如果想使用foreach循環,則必須實現Iterable接口。

public class Test {
    public Test() {
    }

    public static void main(String[] args) {
        MyCollection collection = new MyCollection();
        collection.add("test1");
        collection.add("test2");
        collection.add("test3");
        Iterator iterator = collection.iterator();

        while(iterator.hasNext()) {
            String str = (String)iterator.next();
            System.out.println(str);
        }

        Iterator var5 = collection.iterator();

        while(var5.hasNext()) {
            String s = (String)var5.next();
            System.out.println(s);
        }

    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章