定义:提供一个接口顺序访问一个聚合对象中的各个元素,而又不暴露其内部的实现
迭代器模式可以隐藏聚合对象的实现,减少聚合对象的工作
使用迭代器访问元素不保证顺序,除非聚合对象有特别说明保证其顺序,所以千万别假定迭代器遍历出来的元素是有顺序的。
迭代器有内部迭代器和外部迭代器之分,内部迭代器负责迭代,客户不能控制它的迭代算法,只能将操作传递给它,而外部迭代器由客户控制迭代,比如通过next()方法获取下一个元素,所以外部迭代器更具有弹性。
实现:
1.看看Java的聚合对象,如ArrayList
public Iteratoriterator() { return new Itr(); }
private class Itr implements Iterator{ int cursor; // index of next element to return int lastRet = -1; // index of last element returned; -1 if no such int expectedModCount = modCount; public boolean hasNext() { return cursor != size; } @SuppressWarnings("unchecked") public E next() { checkForComodification(); int i = cursor; if (i >= size) throw new NoSuchElementException(); Object[] elementData = ArrayList.this.elementData; if (i >= elementData.length) throw new ConcurrentModificationException(); cursor = i + 1; return (E) elementData[lastRet = i]; } public void remove() { if (lastRet < 0) throw new IllegalStateException(); checkForComodification(); try { ArrayList.this.remove(lastRet); cursor = lastRet; lastRet = -1; expectedModCount = modCount; } catch (IndexOutOfBoundsException ex) { throw new ConcurrentModificationException(); } } @Override @SuppressWarnings("unchecked") public void forEachRemaining(Consumer consumer) { Objects.requireNonNull(consumer); final int size = ArrayList.this.size; int i = cursor; if (i >= size) { return; } final Object[] elementData = ArrayList.this.elementData; if (i >= elementData.length) { throw new ConcurrentModificationException(); } while (i != size && modCount == expectedModCount) { consumer.accept((E) elementData[i++]); } // update once at end of iteration to reduce heap write traffic cursor = i; lastRet = i - 1; checkForComodification(); } final void checkForComodification() { if (modCount != expectedModCount) throw new ConcurrentModificationException(); } }
这就是外部迭代器,客户获得Iterator,自己控制迭代步数和操作
2.自己实现一个迭代器
一个汽车4S店汽车清单(数组实现的),使用迭代器方式为客户提供遍历的方式
package com.jv.designpattern.iterator;public class Car { private String name; private Long price; public String getName() { return name; } public void setName(String name) { this.name = name; } public Long getPrice() { return price; } public void setPrice(Long price) { this.price = price; } }
package com.jv.designpattern.iterator;import java.util.Iterator;public class CarMenu implements Iterable{ private final static int MAX_LENGTH = 10; private int position = 0; Car[] cars ; public CarMenu(){ cars = new Car[MAX_LENGTH]; } public void addCar(Car car) { cars[position++] = car; } @Override public Iterator iterator() { return new CarMenuIterator(cars); } }
package com.jv.designpattern.iterator;import java.util.Iterator;public class CarMenuIterator implements Iterator{ Car[] cars; private int position = 0; public CarMenuIterator(Car[] cars) { this.cars = cars; } @Override public boolean hasNext() { if(0<=position && position
CarMenu实现Iterable接口得到更好的弹性,方便被客户使用
CarMenuIterator实现Iterator接口,重写HashNext和next方法,和其他Java api保持一样的迭代方式,减少客户的实现复杂度