迭代器模式(Iterator):提供一种方法顺序访问一个聚合对象中各个元素,而又不暴露该对象的内部显示。
UML图:
package com.thpin.repository.designpattern; import java.util.ArrayList; import java.util.List; public class IteratorDemo { public static void main(String[] args) { ConcreteAggregate<String> aggregate = new ConcreteAggregate<>(); aggregate.add("a"); aggregate.add("b"); aggregate.add("c"); aggregate.add("d"); Iterator<String> iterator = aggregate.iterator(); while (iterator.hasNext()) { String str = iterator.next(); System.out.println(str); if ("c".equals(str)) { iterator.remove(); } } Iterator<String> iterator2 = aggregate.iterator(); while (iterator2.hasNext()) { String str = iterator2.next(); System.out.println(str); } } } /* * 迭代器接口 * 至少要包含hashNext()和next() */ interface Iterator<E> { boolean hasNext(); E next(); void remove(); } /* * 迭代器,保证可以访问到集合 * java集合框架的迭代器是集合的内类实现 */ class ConcreteIterator<E> implements Iterator<E> { private ConcreteAggregate<E> aggregate; private int cusor = 0; private int current = -1; public ConcreteIterator(ConcreteAggregate<E> aggregate) { this.aggregate = aggregate; } public boolean hasNext() { return cusor != aggregate.size(); } public E next() { current = cusor; E e = aggregate.get(cusor++); return e; } public void remove() { aggregate.remove(current); cusor = current; current = -1; } } /* * 集合接口,要有一个可以获得迭代器的方法 */ abstract class Aggregate<E> { public abstract Iterator<E> iterator(); } /* * 集合,实现迭代器方便,对list做二次封装 * 实际中的迭代器最好直接操作集合底层的数据结构 */ class ConcreteAggregate<E> extends Aggregate<E> { private List<E> list = new ArrayList<>(); public Iterator<E> iterator() { return new ConcreteIterator<E>(this); } public int size() { return list.size(); } public E get(int index) { return list.get(index); } public void remove(int index) { list.remove(index); } public boolean add(E e) { return list.add(e); } public List<E> getList() { return list; } public void setList(List<E> list) { this.list = list; } }结果:
abcdab
d
迭代器模式就是分离了集合对象的遍历行为,抽象出一个迭代器来负责,这样既可以做到不暴露集合的内部结构,又可以让外部代码透明地访问集合的内部数据。迭代器模式已经被很多高级语言的进行了内部封装,自己编写迭代器的地方还是比较少见的。有时间也可以看一下java集合框架,可以对迭代器有更好的理解,实际上集合的实现包括集合体系的组织结构、初始化、增删改查、扩容、特有功能,还有就是迭代器至少占据了集合的四分之一的内容,很重要的。
foreach遍历的集合要实现Iterable接口,集合的顶层接口Collection直接继承Iterable接口,所以单值集合都可以用foreach语句,而Map都有一个entrySet()方法获得Map的Set<Map.Entry>集合,这样遍历这个set完成对Map的遍历。而且对于集合的遍历推荐使用迭代器,正像迭代器模式定义的那样,它隐藏了集合内部实现而且可以完成遍历功能,更安全,具体就可以表现在对集合元素遍历的过程中删除某个元素时,用Iterator没问题,但正常的for循环get取值就可能出问题,底层集合的长度发生了变化会造成下标越界的异常行为。
