迭代器
关于迭代器来说,这种模式属于容器专属的设计模式了。主要用于遍历容器的。
容器的实现
我们都知道对于容器的实现,主要有两种,
- 第一种就是数组,数组的物理地址是连续的,当数组满了以后会扩展数组,这种扩展不是说再原先数组的物理地址上接着往后顺而是,创建一块新的连续内存空间并将原有数据拷贝过来。这样就完成了扩展。
- 第二种是链表,链表的物理地址不是连续的,每个链表对象中最基本的就是有两个属性一个是属性,一个是指向下一个链表元素的指针或者是引用。这样只用把需要添加的元素追加到最后面就行,无需扩容,而只要知道链表的头部就可以获取链表中所有的数据元素了。但是需要获取链表中某一个元素或者添加一个新元素都需要从链表头部开始遍历,这样会影响很大的效率。
而在开发程序的过程中,我们若自己创造了一个容器的话,对于容器的遍历是需要交给容器自己本身实现的,而迭代器的模式就是通过多态来实现的一种十分低耦合的遍历数据过程。对外用户不需要知道容器如何遍历或者容器底层如何实现的,只用通过遍历器就可以访问所有的元素了。
一个简单的容器实现与迭代器实现
列举一个简单的容器实现与迭代器实现。当然这也只是为了演示一下并不具有实际的工作功能
//集合接口
interface setable<E> {
void set(E e);
int size();
}
//迭代器接口
interface iterator<E> {
E next();
boolean hasNext();
}
//个人用单向链表实现的集合类,只用看大概逻辑,请忽略细节。
public class MySet<E> implements setable<E> {
Node header;
private int size;
//获取迭代器
public iterator<E> getIterator() {
return new mysetable();
}
@Override
public void set(E e) {
if (header == null) {
header = new Node(e);
size = 1;
} else {
Node c = header;
int i = 0;
while (c.next != null) {
c = c.next;
i++;
}
size = i + 1;
c.setNext(new Node(e));
}
}
@Override
public int size() {
return size;
}
//链表元素
class Node {
E ee;
Node next;
public Node(E e) {
ee = e;
}
public Node next() {
return next;
}
public void setNext(Node n) {
next = n;
}
}
//迭代器的实现
class mysetable implements iterator<E> {
Node c = header;
@Override
public E next() {
E e = c.ee;
c = c.next;
return e;
}
@Override
public boolean hasNext() {
return c != null;
}
}
}
使用与测试
MySet<String> ms=new MySet<String>();
ms.set("a");
ms.set("b");
ms.set("c");
iterator<String> i=ms.getIterator();
while(i.hasNext())
{
String ss=i.next();
System.out.println(ss);
}
大致既是如此了
总结
对于迭代器,主要是通过多态来实现迭代功能,而用户根本不需要知道集合底层实现从而对于迭代集合来说也交由迭代器来完成,用户只用实现自己的业务即可;即使更换了集合或者集合的底层实现对于业务来说都不用改变什么。