作者:zuoxiaolong8810(左潇龙),转载请注明出处。
各位好,很久没以LZ的身份和各位对话了,前段时间为了更加逼真的解释设计模式,LZ费尽心思给设计模式加入了故事情节,本意是为了让各位在看小说的过程中就可以接触到设计模式,不过写到现在,LZ最深的感触就是,构思故事的时间远远超过了LZ对设计模式本身的研究。
本章介绍迭代器模式,不再采用故事嵌入的讲解方式,主要原因是因为迭代器模式本身有更多需要介绍的东西,如果嵌入到小说当中,会不太方便去阐述这些内容。
另外,由于LZ的大部分设计模式文章主要针对的人群是对设计模式已经有一定了解,希望更加深入理解的程序猿们。所以LZ希望各位在看本篇文章时,可以打开一个初步介绍迭代器模式的文章,对比观看。下面进入正题,我们先来看看百度百科或者说GOF对迭代器模式的定义。
定义:提供一种方法顺序访问一个聚合对象中各个元素,而又不需暴露该对象的内部表示。
从定义中可以看出,迭代器模式是为了在不暴露该对象内部表示的情况下,提供一种顺序访问聚合对象中元素的方法。这种思想在JAVA集合框架中已经体现的淋漓尽致,而且LZ相信每一个接触JAVA的同学都难免要去触碰。
所以LZ这次先不给出迭代器的类图与标准实现,我们先来看看迭代器模式解决了JAVA集合框架中的哪些问题。
为了更加清晰,LZ斗胆写了几个简单的集合类(向JDK类库的缔造者致敬),我们从这几个简单的集合类出发,去仔细体会下定义的意思,下面是LZ分别写的缩小版的ArrayList、LinkedList和HashSet。
package com.iterator;
public class ArrayList<E> {
private static final int INCREMENT = 10;
private E[] array = (E[]) new Object[10];
private int size;
public void add(E e){
if (size < array.length) {
array[size++] = e;
}else {
E[] copy = (E[]) new Object[array.length + INCREMENT];
System.arraycopy(array, 0, copy, 0, size);
copy[size++] = e;
array = copy;
}
}
public Object[] toArray(){
Object[] copy = new Object[size];
System.arraycopy(array, 0, copy, 0, size);
return copy;
}
public int size(){
return size;
}
}
package com.iterator;
public class LinkedList<E> {
private Entry<E> header = new Entry<E>(null, null, null);
private int size;
public LinkedList() {
header.next = header.previous = header;
}
public void add(E e){
Entry<E> newEntry = new Entry<E>(e, header, header.next);
newEntry.previous.next = newEntry;
newEntry.next.previous = newEntry;
size++;
}
public int size(){
return size;
}
public Object[] toArray(){
Object[] result = new Object[size];
int i = size - 1;
for (Entry<E> e = header.next; e != header; e = e.next)
result[i--] = e.value;
return result;
}
private static class Entry<E>{
E value;
Entry<E> previous;
Entry<E> next;
public Entry(E value, Entry<E> previous, Entry<E> next) {
super();
this.value = value;
this.previous = previous;
this.next = next;
}
}
}
package com.iterator;
import java.util.HashMap;
import java.util.Map;
public class HashSet<E> {
private static final Object NULL = new Object();
private Map<E, Object> map = new HashMap<E, Object>();
public void add(E e){
map.put(e, NULL);
}
public int size(){
return map.size();
}
public Object[] toArray(){
return map.keySet().toArray();
}
}
下面我们看看三个类的遍历方式。
package com.iterator;
public class Main {
public static void main(String[] args) {
ArrayList<Integer> arrayList = new ArrayList<Integer>();
for (int i = 1; i <= 11; i++) {
arrayList.add(i);
}
System.out.println("arrayList size:" + arrayList.size());
Object[] arrayListArray = arrayList.toArray();
for (int i = 0; i < arrayListArray.length; i++) {
System.out.println(arrayListArray[i]);
}
System.out.println(