1. 迭代器设计
迭代器是一种模式,它可以使得对于序列类型的数据结构的遍历行为与被遍历的对象分离,即我们无需关心该序列的底层结构是什么样子的。
一般的迭代器对外提供的接口有:
[1] 检查是否至序列末端;
[2] 返回当前的对象;
[3] 过渡到下一个对象。
我们基于以上三点,提供一个迭代器 Interface 。
<<interface>>MyIterator.java
package com.zj.iterator;
public interface MyIterator<T> { boolean end(); T current(); void next(); } |
接下来,设计一个序列,并部署上面设计的迭代器。我们使用一个 ArrayList 作为底层的数据结构,设计一个内部类 LinksIterator 来实现 MyIterator 接口,这样可以提供迭代器功能。通过 public MyIterator<T> browser() 方法返回该迭代器的实例。
Links.java
package com.zj.iterator; import java.util.ArrayList; import java.util.List;
public class Links<T> { private List<T> items = new ArrayList<T>();
public void add(T x) { items .add(x); }
private class LinksIterator implements MyIterator<T> { private int i = 0;
public boolean end() { return i == items .size(); }
public T current() { return items .get( i ); }
public void next() { if ( i < items .size()) i ++; } }
public MyIterator<T> browser() { return new LinksIterator(); }
public static void main(String[] args) { Links<Integer> links = new Links<Integer>(); for ( int i = 1; i < 6; i++) links.add(i); // use MyIterator MyIterator<Integer> myItr = links.browser(); while (!myItr.end()) { System. out .print(myItr.current() + " " ); myItr.next(); } } } |
在 Link2.java 中,我们使用一个匿名内部类替代 Links.java 中内部类的设计。
Links2.java
package com.zj.iterator; import java.util.ArrayList; import java.util.List;
public class Links2<T> { private List<T> items = new ArrayList<T>();
public void add(T x) { items .add(x); }
public MyIterator<T> browser() { return new MyIterator<T>() { private int i = 0;
public boolean end() { return i == items .size(); }
public T current() { return items .get( i ); }
public void next() { if ( i < items .size()) i ++; } }; }
public static void main(String[] args) { Links2<Integer> links = new Links2<Integer>(); for ( int i = 1; i < 6; i++) links.add(i); // use MyIterator MyIterator<Integer> myItr = links.browser(); while (!myItr.end()) { System. out .print(myItr.current() + " " ); myItr.next(); } } } |
2. 使用 Java 提供的迭代器
Java 提供一个专门的迭代器 <<interface>>Iterator ,我们可以对某个序列实现该 interface ,来提供标准的 Java 迭代器。
<<interface>>Iterator.java
package java.util;
public interface Iterator<E> { boolean hasNext(); E next(); void remove(); } |
我们在 Links2.java 的基础上,重新设计并使用实现标准的 Iterator 接口方法。
Links3.java
package com.zj.iterator.standard;
import java.util.ArrayList; import java.util.Iterator; import java.util.List;
public class Links3<T> { private List<T> items = new ArrayList<T>();
public void add(T x) { items .add(x); }
public Iterator<T> iterator() { return new Iterator<T>() { private int index = 0;
public boolean hasNext() { return index < items .size(); }
public T next() { return items .get( index ++); }
public void remove() { // Not implemented throw new UnsupportedOperationException(); } }; }
public static void main(String[] args) { Links3<Integer> links = new Links3<Integer>(); for ( int i = 1; i < 6; i++) links.add(i); // use Standard Iterator Iterator<Integer> myItr = links.iterator(); while (myItr.hasNext()) System. out .print(myItr.next() + " " ); } } |
3.Java 迭代器与 Foreach 语法
Java 中还提供了一个 Iterable 接口,该接口要求提供一个标准的 Iterator 实现。
<<interface>> Iterable.java
package java.lang;
import java.util.Iterator; public interface Iterable<T> { Iterator<T> iterator(); } |
只要实现了该接口,就可以通过 Foreach 语法遍历你的底层序列。 Links4.java 实现了 Iterable 接口,则就可以使用 Foreach 语法遍历它的底层序列。
Links4.java
package com.zj.iterator.standard; import java.util.ArrayList; import java.util.Iterator; import java.util.List;
public class Links4<T> implements Iterable<T> { private List<T> items = new ArrayList<T>();
public void add(T x) { items .add(x); }
public Iterator<T> iterator() { return new Iterator<T>() { private int index = 0;
public boolean hasNext() { return index < items .size(); }
public T next() { return items .get( index ++); }
public void remove() { // Not implemented throw new UnsupportedOperationException(); } }; }
public static void main(String[] args) { Links4<Integer> links = new Links4<Integer>(); for ( int i = 1; i < 6; i++) links.add(i); // use Foreach for (Integer integer : links) System. out .print(integer + " " ); } } |
你也可以提供该接口的多个不同的实现,基于此来提供多个不同功能的迭代器。 Links5.java 中提供了两种不同功能的迭代器,除了常规的顺序遍历迭代器外,还提供一个遍历偶序号元素的迭代器。
Links5.java
package com.zj.iterator.standard;
import java.util.ArrayList; import java.util.Iterator; import java.util.List;
public class Links5<T> implements Iterable<T> { private List<T> items = new ArrayList<T>();
public void add(T x) { items .add(x); }
public Iterator<T> iterator() { return new Iterator<T>() { private int index = 0;
public boolean hasNext() { return index < items .size(); }
public T next() { return items .get( index ++); }
public void remove() { // Not implemented throw new UnsupportedOperationException(); } }; }
public Iterable<T> even() { return new Iterable<T>() { public Iterator<T> iterator() { return new Iterator<T>() { private int index = 0;
public boolean hasNext() { return index < items .size(); }
public T next() { index += 2; return items .get( index - 2); }
public void remove() { // Not implemented throw new UnsupportedOperationException(); } }; } }; }
public static void main(String[] args) { Links5<Integer> links = new Links5<Integer>(); for ( int i = 1; i < 6; i++) links.add(i); // use Foreach default for (Integer integer : links) System. out .print(integer + " " ); System. out .println(); // use Foreach even for (Integer integer : links.even()) System. out .print(integer + " " ); } } |