本文最后更新于:3 years ago
迭代器模式(Iterator Pattern)是 Java 和 .Net 编程环境中非常常用的设计模式。这种模式用于顺序访问集合对象的元素,不需要知道集合对象的底层表示。
迭代器模式属于 行为型模式
如果想了解迭代器模式的具体的介绍,菜鸟教程介绍得比较详细↓菜鸟教程-迭代器模式
结构图
优缺点 优点:
1、它支持以不同的方式遍历一个聚合对象。 2、迭代器简化了聚合类。 3、在同一个聚合上可以有多个遍历。 4、在迭代器模式中,增加新的聚合类和迭代器类都很方便,无须修改原有代码。
缺点: 由于在客户端和真实主题之间增加了代理对象,因此有些类型的迭代器模式可能会造成请求的处理速度变慢。 由于迭代器模式将存储数据和遍历数据的职责分离,增加新的聚合类需要对应增加新的迭代器类,类的个数成对增加,这在一定程度上增加了系统的复杂性。
使用场景 1、访问一个聚合对象的内容而无须暴露它的内部表示。 2、需要为聚合对象提供多种遍历方式。 3、为遍历不同的聚合结构提供一个统一的接口。
实现代码 迭代器这个模式,其实在学Java的时候,相信大家就已经接触过了,所以这里就简单介绍一下。 这个可以去看看ArrayList、LinkList…这些容器的迭代器部分的源码(看源码真的能够学到很多知识!)
新的一天开始了,甲方爸爸为了使你成长,对你提出需求,构造一个容器,可以动态扩展:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 class ArrayList_ { Object[] object = new Object[10 ]; private int index = 0 ; public void add (Object o) { if (index == object.length){ Object[] newObject = new Object[object.length*2 ]; System.arraycopy(object, 0 , newObject, 0 , object.length); object = newObject; } object[index++] = o; } public int size () { return index; } }class LinkList_ { Node head = null ; Node tail = null ; private int index = 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; index++; } private class Node { private Object object; Node next; public Node (Object o) { object = o; } } public int size () { return index; } }
这里实现了两种容器,一种是用数组来实现的,一种是用链表实现的。(任何容器都是由这两种结构来实现的)
接着将两种容器,整合一下,实现容器的替换。这里我们只要将两种容器实现一个接口就行了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 public interface Collection_ { void add (Object o) ; int size () ; }public class ArrayList_ implements Collection_ { Object[] object = new Object[10 ]; private int index = 0 ; @Override public void add (Object o) { if (index == object.length){ Object[] newObject = new Object[object.length*2 ]; System.arraycopy(object, 0 , newObject, 0 , object.length); object = newObject; } object[index++] = o; } @Override public int size () { return index; } }public class LinkList_ implements Collection_ { Node head = null ; Node tail = null ; private int index = 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; index++; } private class Node { private Object object; Node next; public Node (Object o) { object = o; } } public int size () { return index; } }public class Main { public static void main (String[] args) { Collection_ list = new ArrayList_(); for (int i = 0 ; i < 20 ; i++) { list.add(new String("s" ) + i); } System.out.println(list.size()); } }
ArrayList_和LinkList_都实现了Collection_接口,重写了add()和size()方法。
到这里,前期准备工作就完成了。
接着,甲方爸爸又提出新的需求,我要将容器中的所有数据取出来,并且这个遍历是通用的。 也就是我数组容器可以遍历,链表容器也可以遍历,以后的Hash,Queue…都可以用这个遍历。
麻烦了
ArrayList_ al = (ArrayList_)list;for (int i = 0 ; i < al.size(); i++) { }
你是不是准备这样做,但是甲方爸爸不让你这样做。
于是咋办,你想了想,计从心来:
创建一个Iterator接口,然后让这些容器,自己来实现这些遍历
你很快写下来以下代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 public interface Iterator_ { boolean hasNext () ; Object next () ; }public interface Collection_ { void add (Object obj) ; int size () ; Iterator_ iterator () ; }public class ArrayList_ implements Collection_ { Object[] objects = new Object[10 ]; private int index = 0 ; @Override public void add (Object obj) { if (index == objects.length){ Object[] newObject = new Object[objects.length*2 ]; System.arraycopy(objects, 0 , newObject, 0 , objects.length); objects = newObject; } objects[index++] = obj; } @Override public int size () { return index; } @Override public Iterator_ iterator () { return new ArrayListIterator(); } private class ArrayListIterator implements Iterator_ { private int currentIndex = 0 ; @Override public boolean hasNext () { if (index > currentIndex) return true ; else return false ; } @Override public Object next () { Object obj = objects[currentIndex]; currentIndex++; return obj; } } }public class LinkList_ implements Collection_ { Node head = null ; Node tail = null ; private int index = 0 ; @Override public void add (Object obj) { Node node = new Node(obj); node.next = null ; if (head == null ) { head = node; tail = node; } tail.next = node; tail = node; index++; } private class Node { Object o; Node next; public Node (Object o) { this .o = o; } } @Override public int size () { return index; } @Override public Iterator_ iterator () { return new ArrayListIterator(); } private class ArrayListIterator implements Iterator_ { private int currentIndex = 0 ; private Node tmp = head; private Node lastReturn; @Override public boolean hasNext () { if (index > currentIndex) return true ; else return false ; } @Override public Object next () { lastReturn = tmp; tmp = tmp.next; currentIndex++; return lastReturn.o; } } }public class Main { public static void main (String[] args) { Collection_ list = new LinkList_(); for (int i = 0 ; i < 20 ; i++) { list.add(new String("s" ) + i); } Iterator_ iterator = list.iterator(); while (iterator.hasNext()){ Object next = iterator.next(); System.out.println(next); } } }
这里是将,Iterator接口定义在Collection接口中,然后由容器内部将Iterator接口实现(完美)
就这样,你又一次完成了甲方爸爸的需求,但是你没有上次开心,是啊,摸鱼划水谁不想呢?