迭代器模式提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部的表示。
迭代器模式让我们能游走于聚合内的每一个元素,而又不暴露内部的表示。把游走的任务放在迭代器上,而不是聚合上,这样简化了聚合的接口和实现,也让责任各得其所。
在设计中使用迭代器的影响是明显的:如果你有一个统一的方法访问聚合中的每一个对象,你就可以编写多态的代码和这些聚合搭配使用,只要有了迭代器这个方法,根本不管迭代的究竟是由数组还是由ArrayList(或者其他能创建迭代器的东西)来保存的。另一个重要影响是迭代器模式把这些元素之间游走的责任交给迭代器,而不是聚合对象。这不仅让聚合的接口和实现变得更简洁,也可以让聚合更专注在它所应该专注的事情上面(也就是管理对象组合),而不必去理会遍历的事情。
使用场景:
1、访问一个聚合对象的内容而无须暴露它的内部表示。
2、需要为聚合对象提供多种遍历方式。
3、为遍历不同的聚合结构提供一个统一的接口。
事实上JAVA 中的 iterator就是迭代器模式的一个具体体现。
二、示例演示
1、业务需求
利用迭代器实现集合遍历。
2、创建一个Iterator 接口和一个返回迭代器的 Container 接口
Iterator.java public interface Iterator { public boolean hasNext(); public Object next(); } Container.java public interface Container { public Iterator getIterator(); }
3、实现一个名字的迭代器实体类和一个获取该迭代器的实体类
NameIterator.java public class NameIterator implements Iterator { private String names[] = {"Kang" , "Jack" ,"Tom" , "Jerry"}; private int index; @Override public boolean hasNext() { if(index < names.length){ return true; } return false; } @Override public Object next() { if(this.hasNext()){ return names[index++]; } return null; } } NameRepository.java public class NameRepository implements Container { @Override public Iterator getIterator() { return new NameIterator(); } }
4、测试
public class TestDemo { public static void main(String[] args) { NameRepository namesRepository = new NameRepository(); for(Iterator iter = namesRepository.getIterator(); iter.hasNext();){ String name = (String)iter.next(); System.out.println("Name : " + name); } } }
结果如下:
Name : Kang
Name : Jack
Name : Tom
Name : Jerry
改进:这里迭代器的内容是在内部定义好的,事实上我们可以定义一个带参数的构造器,将待迭代的内容传入构造器中,从而让迭代器迭代我们需要迭代的集合对象。
三、总结
Java有一个内置的Iterator接口:
public interface Iterator<E> { /** * Returns true if there is at least one more element, false otherwise. * @see #next */ public boolean hasNext(); /** * Returns the next object and advances the iterator. * * @return the next object. * @throws NoSuchElementException * if there are no more elements. * @see #hasNext */ public E next(); /** * Removes the last object returned by {@code next} from the collection. * This method can only be called once between each call to {@code next}. * * @throws UnsupportedOperationException * if removing is not supported by the collection being * iterated. * @throws IllegalStateException * if {@code next} has not been called, or {@code remove} has * already been called after the last call to {@code next}. */ public void remove(); }
由于迭代器模式将存储数据和遍历数据的职责分离,增加新的聚合类需要对应增加新的迭代器类,类的个数成对增加,这在一定程度上增加了系统的复杂性。