目录
迭代器模式(Iterator)
(1)优点
(2)缺点
(3)使用场景
(4)注意事项
(5)应用实例:
代码
迭代器模式(Iterator)
迭代器模式(Iterator Pattern)是Java和.Net编程环境中非常常用的设计模式。这种模式用于顺序访问集合对象的元素,不需要知道集合对象的底层表示。迭代器模式属于行为型模式。迭代器模式已经被淘汰,java中已经把迭代器运用到各个聚集类(collection)中了,使用java自带的迭代器就已经满足我们的需求了。
【我爱上了Mary,不顾一切的向她求婚。Mary:“想要我跟你结婚,得答应我的条件”我:“什么条件我都答应,你说吧”Mary:“我看上了那个一克拉的钻石”我:“我买,我买,还有吗?”Mary:“我看上了湖边的那栋别墅” 我:“我买,我买,还有吗?”Mary:“我看上那辆法拉利跑车”我脑袋嗡的一声,坐在椅子上,一咬牙:“我买,我买,还有吗?”
迭代模式:迭代模式可以顺序访问一个聚集中的元素而不必暴露聚集的内部表象。多个对象聚在一起形成的总体称之为聚集,聚集对象是能够包容一组对象的容器对象。迭代子模式将迭代逻辑封装到一个独立的子对象中,从而与聚集本身隔开。
迭代模式简化了聚集的界面。每一个聚集对象都可以有一个或一个以上的迭代子对象,每一个迭代子的迭代状态可以是彼此独立的。迭代算法可以独立于聚集角色变化。】
意图:提供一种方法顺序访问一个聚合对象中各个元素, 而又无须暴露该对象的内部表示。
主要解决:不同的方式来遍历整个整合对象。
何时使用:遍历一个聚合对象。
如何解决:把在元素之间游走的责任交给迭代器,而不是聚合对象。
关键代码:定义接口:hasNext, next。
(1)优点
1、它支持以不同的方式遍历一个聚合对象。
2、迭代器简化了聚合类。
3、在同一个聚合上可以有多个遍历。
4、在迭代器模式中,增加新的聚合类和迭代器类都很方便,无须修改原有代码。
(2)缺点
由于迭代器模式将存储数据和遍历数据的职责分离,增加新的聚合类需要对应增加新的迭代器类,类的个数成对增加,这在一定程度上增加了系统的复杂性。
(3)使用场景
1、访问一个聚合对象的内容而无须暴露它的内部表示。
2、需要为聚合对象提供多种遍历方式。
3、为遍历不同的聚合结构提供一个统一的接口。
(4)注意事项
迭代器模式就是分离了集合对象的遍历行为,抽象出一个迭代器类来负责,这样既可以做到不暴露集合的内部结构,又可让外部代码透明地访问集合内部的数据。
(5)应用实例:
JAVA 中的 iterator。
代码
//E:是泛型,可以是Object等类型
public interface Iterator_<E> { //Element //Type //K //Value V Tank
//public interface Iterator_ {
boolean hasNext();
//Object next();//当为泛型时,中间不需要类型强转
E next(); //Tank next() Iterator_<Tank> it = ... Tank t = it.next();
}
public interface Collection_<E> {
//public interface Collection_{
//E:是泛型,可以是Object等类型
void add(E o);
int size();
Iterator_ iterator();
}
/**
* 用数组来实现一个容器
* 相比数组,这个容器不用考虑边界问题,可以动态扩展
*/
//E:是泛型,可以是Object等类型
class ArrayList_<E> implements Collection_<E> {
//class ArrayList_ implements Collection_ {
//Object[] objects = new Object[10];
E[] objects = (E[])new Object[10];
//objects中下一个空的位置在哪儿,或者说,目前容器中有多少个元素
private int index = 0;
public void add(E o) {
if(index == objects.length) {
E[] newObjects = (E[])new Object[objects.length*2];
System.arraycopy(objects, 0, newObjects, 0, objects.length);
objects = newObjects;
}
objects[index] = o;
index ++;
}
public int size() {
return index;
}
//
@Override
public Iterator_<E> iterator() {
return new ArrayListIterator();
}
private class ArrayListIterator<E> implements Iterator_<E> {
private int currentIndex = 0;
@Override
public boolean hasNext() {
if(currentIndex >= index) return false;
return true;
}
@Override
public E next() {
E o = (E)objects[currentIndex];
currentIndex ++;
return o;
}
}
}
/**
* 用链表来实现一个容器
* 相比数组,这个容器不用考虑边界问题,可以动态扩展
*/
class LinkedList_ implements Collection_ {
Node head = null;
Node tail = null;
//目前容器中有多少个元素
private int size = 0;
public void add(Object o) {
Node n = new Node(o);
n.next = null;
if(head == null) {
head = n;
tail = n;
}
tail.next = n;
tail = n;
size++;
}
private class Node {
private Object o;
Node next;
public Node(Object o) {
this.o = o;
}
}
public int size() {
return size;
}
//
@Override
public Iterator_ iterator() {
return null;
}
}
/**
* v1:构建一个容器,可以添加对象
* v2:用链表来实现一个容器
* v3:添加容器的共同接口,实现容器的替换
* v4:如何对容器遍历呢?
* v4:用一种统一的遍历方式,要求每一个容器都要提供Iterator的实现类
* 作业:实现LinkedList的Iterator
* v6:JDK的容器实现
* v7:实现泛型版本
*/
public class Main {
public static void main(String[] args) {
//用链表来实现一个容器
//Collection_ list = new LinkedList_();
//用数组来实现一个容器
//Collection_ list = new ArrayList_();
Collection_<String> list = new ArrayList_<>();
for(int i=0; i<15; i++) {
list.add(new String("s" + i));
}
System.out.println(list.size());
/*
//ArrayList_如果用这种遍历方式,就不能实现通用了
ArrayList_ al = (ArrayList_)list;
for(int i=0; i<al.size(); i++) {
//如果用这种遍历方式,就不能实现通用了
}
*/
//这个接口的调用方式:
Iterator_<String> it = list.iterator();
while(it.hasNext()) {
String o = it.next();
System.out.println(o);
}
/*
//JDK的容器的Iterator
Collection c = new ArrayList();
for(int i=0; i<15; i++) {
c.add(new String("s" + i));
}
Iterator it = c.iterator();
while(it.hasNext()) {
System.out.println(it.next());
}
*/
}
}