迭代器模式(Iterator Pattern)又叫作游标模式(CursorPattern),它提供一种按顺序访问集合/容器对象元素的方法,而又无须暴露集合内部表示。迭代器模式可以为不同的容器提供一致的遍历行为,而不用关心容器内元素的组成结构,属于行为型设计模式。
迭代器模式的应用场景:
- 访问一个集合对象的内容而无须暴露它的内部表示
- 为遍历不同的集合结构提供一个统一的访问接口
java 中提供了两个接口:
- java.util.Iterable:提供了获取迭代器的方法 iterator()
- java.util.Iterator:迭代器接口,提供了 hasNext()、next()、remove() 方法
示例:一个只有 add 和 遍历 的简单容器
1、链表实现
public class LinkedContainer<E> implements Iterable<E> {
private class Node<E> {
E element;
Node<E> next;
public Node(E element) {
this.element = element;
this.next = null;
}
}
private Node<E> head;
private Node<E> tail;
private int size;
public LinkedContainer() {
this.head = null;
this.tail = null;
this.size = 0;
}
public void add(E element){
Node<E> node = new Node<>(element);
if (head == null) {
head = node;
} else {
tail.next = node;
}
tail = node;
size++;
}
@Override
public Iterator<E> iterator() {
return new ContainerIter();
}
class ContainerIter implements Iterator<E> {
private Node<E> curr;
public ContainerIter() {
this.curr = head;
}
@Override
public boolean hasNext() {
return curr != null;
}
@Override
public E next() {
E res = curr.element;
curr = curr.next;
return res;
}
}
}
2、数组实现
@SuppressWarnings("unchecked")
public class ArrayContainer<E> implements Iterable<E> {
@Override
public Iterator<E> iterator() {
return new ArrayIter<>();
}
private Object[] elements;
private int size;
public ArrayContainer(int capacity) {
this.size = 0;
elements = new Object[capacity];
}
public ArrayContainer() {
this(16);
}
public void add(E element) {
if (size == elements.length) {
// 动态扩容
elements = Arrays.copyOf(elements, elements.length * 2);
}
elements[size++] = element;
}
private class ArrayIter<E> implements Iterator<E> {
int pos;
@Override
public boolean hasNext() {
return pos < size;
}
@Override
public E next() {
return (E) elements[pos++];
}
}
}
遍历示例:在 java 中,针对实现了 Iterable 和 Iterator 的类,支持两种遍历方式
1、原始的方式:
- 先获取迭代器 iter = Iterable.iterator();
- 再通过 while(iter.hasNext()){ iter.next(); } 循环进行遍历
```java
LinkedContainer
container = new LinkedContainer<>(); container.add(“世界”); container.add(“如此”); container.add(null); container.add(“我么”); container.add(null);
// 1.获取迭代器
Iterator
2、使用 foreach 语法糖
- **foreach 不支持在遍历过程中删除元素**
- **iterator 支持在迭代过程中删除元素**
```java
LinkedContainer<String> container = new LinkedContainer<>();
container.add("世界");
container.add("如此");
container.add(null);
container.add("我么");
container.add(null);
for (String s : container) {
System.out.println(s);
}