迭代器,提供了在不了解集合内部实现方法的时候遍历集合的能力。可以将容器内部实现与遍历操作隔离、解耦。
通过自定义一个简单集合,并在对其使用迭代器进行遍历,达到掌握迭代器的目的。
一个简单的集合,规则如下
/** * 自定义集合 * 功能: 只能插入三个元素, 插入第四个元素会替换集合中第一个元素 * 实现了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); } } }