一、前言
参考视频:马士兵-设计模式-Iterator
参考书目:图解设计模式
环境:
- IDEA
- Maven
- Junit
Iterator模式是用于遍历集合类的bai标准访问方du法。它可以把访问逻辑从不同类型的集合zhi类中抽象出来,从而避免向dao客户端暴露集合的内部结构。
例如,如果没有使用Iterator,遍历一个数组的方法是使用索引:
for(int i=0; i<array.size(); i++) { ... get(i) ... }
而访问一个链表(LinkedList)又必须使用while循环:
while((e=e.next())!=null) { ... e.data() ... }
以上两种方法客户端都必须事先知道集合的内部结构,访问代码和集合本身是紧耦合,无法将访问逻辑从集合类和客户端代码中分离出来,每一种集合对应一种遍历方法,客户端代码无法复用。
更恐怖的是,如果以后需要把ArrayList更换为LinkedList,则原来的客户端代码必须全部重写。
为解决以上问题,Iterator模式总是用同一种逻辑来遍历集合:
for(Iterator it = c.iterater(); it.hasNext(); ) { ... }
奥秘在于客户端自身不维护遍历集合的"指针",所有的内部状态(如当前元素位置,是否有下一个元素)都由Iterator来维护,而这个Iterator由集合类通过工厂方法生成,因此,它知道如何遍历整个集合。
客户端从不直接和集合类打交道,它总是控制Iterator,向它发送"向前","向后","取当前元素"的命令,就可以间接遍历整个集合。
二、关系图
三、代码
路径:
代码:
Iterator_:
package Iterator;
/**
* @Autord: HuangDekai
* @Date: 2020/9/28 13:55
* @Version: 1.0
* @since: jdk11
*/
public interface Iterator_ {
boolean hasNext();
Object next();
}
Collection_:
package Iterator;
/**
* @Autord: HuangDekai
* @Date: 2020/9/28 13:59
* @Version: 1.0
* @since: jdk11
*/
public interface Collection_ {
Iterator_ iterator();
void add(Object object);
int Size();
}
ArrayList_:
package Iterator;
/**
* @Autord: HuangDekai
* @Date: 2020/9/28 14:08
* @Version: 1.0
* @since: jdk11
*/
public class ArrayList_ implements Collection_ {
private Object[] objects = new Object[10];
private int index = 0;
@Override
public Iterator_ iterator() {
return new ArrayIterator();
}
//私有内部类实现ArrayIterator
private class ArrayIterator implements Iterator_{
int currentIndex = 0;
@Override
public boolean hasNext() {
if (currentIndex >= index) return false;
return true;
}
@Override
public Object next() {
Object o = objects[currentIndex];
currentIndex++;
return o;
}
}
@Override
public void add(Object object) {
if (index >= objects.length){
Object[] newObjects = new Object[objects.length*2];
System.arraycopy(objects,0,newObjects,0,objects.length);
objects = newObjects;
}
objects[index] = object;
index++;
}
@Override
public int Size() {
return index;
}
}
LinkedList_
package Iterator;
/**
* @Autord: HuangDekai
* @Date: 2020/9/28 14:52
* @Version: 1.0
* @since: jdk11
*/
public class LinkedList_ implements Collection_{
Node head = null;
Node tail = null;
private int size = 0;
private class Node{
Object data = null;
Node next = null;
public Node(Object o){
data = o;
}
}
@Override
public Iterator_ iterator() {
return new LinkedListIterator();
}
private class LinkedListIterator implements Iterator_{
private Node currentNode = head;
@Override
public boolean hasNext() {
if (currentNode == null) return false;
return true;
}
@Override
public Object next() {
Object data = currentNode.data;
currentNode = currentNode.next;
return data;
}
}
@Override
public void add(Object object) {
Node node = new Node(object);
node.next = null;
if (head == null){
head = node;
tail = node;
}
tail.next = node;
tail = node;
size++;
}
@Override
public int Size() {
return size;
}
}
四、测试样例
路径
代码
package Iterator;
import org.junit.Test;
/**
* @Autord: HuangDekai
* @Date: 2020/9/28 15:35
* @Version: 1.0
* @since: jdk11
*/
public class IteratorTest {
@Test
public void ArrayListTest(){
Collection_ list = new ArrayList_();
for (int i = 0; i < 11; i++) {
list.add(new String("a"+i));
}
Iterator_ it = list.iterator();
while (it.hasNext()){
System.out.println(it.next());
}
}
@Test
public void LinkedListTest(){
Collection_ list = new ArrayList_();
for (int i = 0; i < 11; i++) {
list.add(new String("b"+i));
}
Iterator_ it = list.iterator();
while (it.hasNext()){
System.out.println(it.next());
}
}
}
可以看到,通过使用迭代器,其实两个测试代码差别只有一行,即不同的Collection_的实现。
结果: