用于顺序访问集合对象的元素,不需要关心集合内部的层次结构。
角色
抽象聚合(Aggregate):包含集合对象的访问接口(包括且不限于:get / add / set / remove)以及迭代器创建接口的定义
具体聚合(ConcreteAggregate):抽象聚合的实现类
抽象迭代器(Iterator):包含访问和遍历集合元素接口的定义,主要包含 hasNext()、next() 等方法。
具体迭代器(Concretelterator):抽象迭代器的实现类,通过记录下一个元素位置(cursor)和上一元素位置(lastRet)实现
抽象聚合 Aggregate
public abstract class Aggregate<E> {
public abstract void set(int index, E element);
public abstract void add(E element);
public abstract void remove();
public abstract Iterator<Aggregate<E>> iterator();
}
具体聚合 ConcreteAggregate
public class ConcreteAggregate<E> extends Aggregate<E> {
private E[] elementData;
private int size;
public ConcreteAggregate(E[] elementData) {
this.elementData = elementData;
this.size = elementData.length;
}
@Override
public void set(int index, E element) {
if (index < 0 || index >= elementData.length) {
throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
}
elementData[index] = element;
}
@Override
public void add(E element) {
//TODO:
}
@Override
public void remove() {
//TODO:
}
@Override
public Iterator<Aggregate<E>> iterator() {
return new Concretelterator(elementData);
}
}
抽象迭代器 Iterator
public interface Iterator<E> {
boolean hasNext();
E next();
}
具体迭代器 Concretelterator
import java.util.NoSuchElementException;
public class Concretelterator implements Iterator {
private int cursor;
private int lastRet = -1;
private int size;
private Object[] elementData;
public Concretelterator(Object[] elementData) {
this.elementData = elementData;
this.size = elementData.length;
}
@Override
public boolean hasNext() {
return cursor != size;
}
@Override
public Object next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
int i = cursor;
cursor = i + 1;
return elementData[lastRet = i];
}
}
测试类
public class IteratorTester {
public static void main(String args[]) {
String[] strs = new String[] {
"zero", "one", "two", "three", "four"//, "five", "six", "seven", "eight", "nine"
};
Aggregate aggregate = new ConcreteAggregate(strs);
Iterator<Aggregate> iterator = aggregate.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
}
}
zero
one
two
three
four
举例:数组迭代器
抽取 ArrayList 中 Itr 和 ListItr 的源码组装而成
public interface Iterator<E> {
boolean hasNext();
int nextIndex();
E next();
boolean hasPrevious();
int previousIndex();
E previous();
void set(E element);
void add(E element);
void remove();
void reset();
void from(int index);
}
import java.util.Arrays;
import java.util.ConcurrentModificationException;
import java.util.NoSuchElementException;
public class ConcreteIterator<E> implements Iterator<E> {
private static final int DEFAULT_CAPACITY = 10;
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
int cursor, lastRet = -1, size;
private E[] elementData;
public ConcreteIterator(E[] data, int index) {
this.elementData = data;
this.size = data.length;
this.cursor = index;
}
@Override
public boolean hasNext() {
return cursor != size;
}
@Override
public int nextIndex() {
return cursor;
}
@Override
public E next() {
int i = cursor;
if (i >= size)
throw new NoSuchElementException();
if (i >= elementData.length)
throw new ConcurrentModificationException();
cursor = i + 1;
return elementData[lastRet = i];
}
@Override
public boolean hasPrevious() {
return cursor != 0;
}
@Override
public int previousIndex() {
return cursor - 1;
}
@Override
public E previous() {
int i = cursor - 1;
if (i < 0)
throw new NoSuchElementException();
if (i >= elementData.length)
throw new ConcurrentModificationException();
cursor = i;
return elementData[lastRet = i];
}
@Override
public void set(E element) {
if (lastRet < 0)
throw new IllegalStateException();
try {
int index = lastRet;
if (index >= size)
throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
E oldValue = elementData[index];
elementData[index] = element;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
@Override
public void add(E element) {
try {
int i = cursor;
int index = i;
if (index > size || index < 0)
throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
int minCapacity = size + 1;
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
}
int minExpand = (elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA) ? 0 : DEFAULT_CAPACITY;
if (minCapacity > minExpand) {
if (minCapacity - elementData.length > 0) {
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0) {
if (minCapacity < 0) {
throw new OutOfMemoryError();
}
newCapacity = (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE;
}
elementData = Arrays.copyOf(elementData, newCapacity);
}
}
System.arraycopy(elementData, index, elementData, index + 1, size - index);
elementData[index] = element;
size++;
cursor = i + 1;
lastRet = -1;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
@Override
public void remove() {
if (lastRet < 0)
throw new IllegalStateException();
try {
int index = lastRet;
if (index >= size)
throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
E oldValue = elementData[index];
int numMoved = size - index - 1;
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index, numMoved);
elementData[--size] = null;
cursor = lastRet;
lastRet = -1;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
@Override
public void reset() {
this.cursor = 0;
this.lastRet = -1;
}
@Override
public void from(int index) {
this.cursor = index;
this.lastRet = index - 1;
}
}
public class IteratorTester {
public static void main(String args[]) {
String[] strs = new String[] {
"zero", "one", "two", "three", "four"//, "five", "six", "seven", "eight", "nine"
};
String element;
Iterator<String> iterator = new ConcreteIterator(strs, 0);
System.out.println("original data:");
while (iterator.hasNext()) {
System.out.println("[" + iterator.nextIndex() + "]" + iterator.next());
}
boolean hasDone = false;
iterator.reset();
while (iterator.hasNext()) {
element = iterator.next();
if (hasDone)
System.out.println("[" + iterator.previousIndex() + "]" + element);
if (!hasDone && iterator.previousIndex() == 1) {
iterator.set("update");
hasDone = true;
iterator.reset();
System.out.println("\nafter set:");
}
}
hasDone = false;
iterator.reset();
while (iterator.hasNext()) {
element = iterator.next();
if (hasDone)
System.out.println("[" + iterator.previousIndex() + "]" + element);
if (!hasDone && iterator.previousIndex() == 3) {
iterator.add("insert");
hasDone = true;
iterator.reset();
System.out.println("\nafter add:");
}
}
iterator.reset();
hasDone = false;
while (iterator.hasNext()) {
element = iterator.next();
if (hasDone)
System.out.println("[" + iterator.previousIndex() + "]" + element);
if (!hasDone && iterator.previousIndex() == 2) {
iterator.remove();
hasDone = true;
iterator.reset();
System.out.println("\nafter remove:");
}
}
}
}
original data:
[0]zero
[1]one
[2]two
[3]three
[4]four
after set:
[0]zero
[1]update
[2]two
[3]three
[4]four
after add:
[0]zero
[1]update
[2]two
[3]three
[4]insert
[5]four
after remove:
[0]zero
[1]update
[2]three
[3]insert
[4]four