一篇文章看懂java迭代器

7次阅读

共计 2619 个字符,预计需要花费 7 分钟才能阅读完成。

概述

迭代器,提供了在不了解集合内部实现方法的时候遍历集合的能力。可以将容器内部实现与遍历操作隔离、解耦。

使用迭代器实现一个简单集合

通过自定义一个简单集合,并在对其使用迭代器进行遍历,达到掌握迭代器的目的。

集合描述

一个简单的集合,规则如下

  • 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);
        }

    }
}

正文完
 0