在讲这个设计模式之前,我先讲一下一个容器如何具体去实现,我们都知道ArrayList数组可以往里面增加元素,那么既然是一个数组为何可以不用担心它溢出呢?因为在这个容器中,它可以自动扩容,那么具体去如何实现?
首先我们都知道,一个容器,必须有一个往里面添加元素的方法:
public void add(Object o){
if(count == object.length) {
Object[] newObj = new Object[2 * object.length];
System.arraycopy(object, 0, newObj, 0, object.length);
}
object[count] = o;
count++;
}
这里的count是元素的个数,也就是说这个if判断当前的集合元素是否已经满了,如过满了的话,那么就对这个数组进行扩容,然后把的原来数组COPY到新的数组中,然后进行赋值。
获取数组的元素个数:
public int length(){
return count;
}
假如说我们再创建一个链表容器:
public class myList {
private Node head = null;
private Node tail = null;
private int size = 0;
public void add(Object o) {
Node n = new Node(o, null);
if(head == null){
head = n;
tail = n;
}
tail.setN(n);
tail = n;
size++;
}
public int length() {
return size;
}
}
这里容器的建立原理跟数组差不多,首先新建一个结点,把数据放入这个新结点的数据域,然后把指针域设置为空,然后再将他放入链表的尾部,再使尾指针指向该结点。
那么我在接下来使用这两个容器的时候,假如说我在使用其中某一个:
public class Test {
public static void main(String[] args) {
MyArrayList arr = new MyArrayList();
for(int i = 0; i < 3; ++i){
arr.add(i);
}
}
}
这时候我突然,不想用数组,我想用链表容器,那么假设后面有很大一堆代码,那么我接下来是不是后面所有的代码都得改?那么有没有办法解决呢?答案肯定是有的,那么我们需要定义一个接口,让所有的容器去实现它里面的方法,那么采用多态调用,就可以实现后面的代码不用动。
public class Test {
public static void main(String[] args) {
Collection arr = new MyArrayList();
for(int i = 0; i < 3; ++i){
arr.add(1);
}
}
}
那么根据这个原理,我们想在遍历某个容器的时候,假如我们在遍历数组容器,然后后来我不想用数组容器了,我想用链表容器,那么这时候,我们都知道,遍历数组跟遍历链表的方式肯定是不一样的。那么这时候我们是不是还要傻傻的去改变代码呢?
其实这时候我们就要需要用到迭代器了,我们把遍历容器这个功能独立出来,并且增加接口去实现这个功能,这样就弱化了类之间的耦合性,增强了代码的复用性,可维护性和灵活性。
定义接口:
/*
* 定义两个方法,让容器去实现它,判断下一个是否有值,以及获取下一个元素的值
*/
public interface Iterator {
Object next();
boolean hasNext();
}
一个使获取下一个元素,另一个判断后面是否还有元素,返回的数据类型使boolean,如果有返回true,否者返回false,然后让容器去实现这两个功能。
实现代码:
private class arrayListIterator implements Iterator{
int currentIndex = 0;
public boolean hasNext() {
if(currentIndex >= count) return false;
else return true;
}
public Object next(){
Object o = object[currentIndex];
currentIndex++;
return o;
}
}
那么在遍历的时候,我们就得到统一:
public class Test {
public static void main(String[] args) {
Collection arr = new MyArrayList();
for(int i = 0; i < 3; ++i){
arr.add(i);
}
Iterator i = arr.iterator();
while(i.hasNext()){
System.out.println(i.next());
}
}
}
那么就如这时候我们想使用链表容器:
public class Test {
public static void main(String[] args) {
Collection arr = new myList();
for(int i = 0; i < 3; ++i){
arr.add(i);
}
arr.add(2);
Iterator i = arr.iterator();
while(i.hasNext()){
System.out.println(i.next());
}
}
}
这时候后面的代码都不用改。在我们的实际运用中,这种情况使很常见的,那么利用迭代器,还是像前面所说,弱化了类之间的耦合性,增强了代码的复用性,可维护性和灵活性。