迭代器模式(Iterator Pattern)
属于行为型模式
的一种,提供一种方法访问一个容器中各个元素,而又不须要暴露该对象的内部细节。java
<!-- more -->git
迭代器模式
听起来可能感受很陌生,可是实际上,迭代器模式
是全部设计模式中最简单也是最经常使用的设计模式,正是由于太经常使用了,因此致使不少人忽略了它的存在。spring
在实际的开发过程当中,咱们可能须要针对不一样的需求,可能须要以不一样的方式来遍历整个整合对象,但又不但愿在聚合对象的抽象接口层中充斥着各类不一样的便利操做。这个时候咱们就须要这样一种东西,它应该具有以下三个功能:设计模式
迭代器模式: 把在元素之间游走的责任交给迭代器,而不是聚合对象。简化了聚合的接口和实现,让聚合更专一在它所应该专一的事情上,这样作更加符合单一责任原则。springboot
UML结构图微信
模式结构微信公众平台
具体迭代器
须要实现的接口,提供了游走聚合对象元素之间的方法createIterator()
用于建立一个迭代器对象,充当抽象迭代器工厂角色createIterator()
,该方法返回一个与该具体聚合类对应的具体迭代器ConcreteIterator
实例。UML图以下:ide
1.先定义抽象迭代器``测试
interface Iterator<E> { //判断是否有还有下一个元素 boolean hasNext(); //取出下一个对象 E next(); }
2.在定义一个具体迭代器对象,实现了Iterator
中的方法ui
class MusicIterator<E> implements Iterator<E> { private E[] es; private int position = 0; public MusicIterator(E[] es) { this.es = es; } @Override public boolean hasNext() { return position != es.length; } @Override public E next() { E e = es[position]; position += 1; return e; } }
3.接下来定义抽象聚合类(常为 Collection , List , Set 等)
interface AbstractList<E> { void add(E e); Iterator<E> createIterator(); }
4.最后建立具体聚合类 (常为 ArrayList , HashSet 等,是抽象聚合类的实现类)
class MusicList implements AbstractList<String> { private String[] books = new String[5]; private int position = 0; @Override public void add(String name) { books[position] = name; position += 1; } @Override public Iterator<String> createIterator() { return new MusicIterator<>(books); } }
5.建立测试工程
public class Client { public static void main(String[] args) { AbstractList<String> list = new MusicList(); list.add("凉凉"); list.add("奇谈"); list.add("红颜"); list.add("伴虎"); list.add("在人间"); Iterator<String> iterator = list.createIterator(); while (iterator.hasNext()) { System.out.println(iterator.next()); } } }
6.运行效果
凉凉 奇谈 红颜 伴虎 在人间
至此一个简单的迭代器
就完成了,实现了对容器的遍历。能够看到迭代器在Client
中遍历时根本不须要知道他底层的实现,只须要经过迭代器来遍历就能够了。
上文介绍了本身实现一个简单的迭代器
,看完的应该就不陌生了,它其实在JAVA的不少集合类中被普遍应用,接下来看看JAVA源码中是如何使用迭代器模式的。
List<String> list = new ArrayList<>(); Iterator<String> iterator = list.iterator(); while (iterator.hasNext()) { System.out.println(iterator.next()); }
看完这段代码是否是很熟悉,与咱们上文代码基本相似
Iterator
接口的具体迭代器对象接下来看下ArrayList
中的iterator
是如何实现的
public Iterator<E> iterator() { return new Itr(); } private class Itr implements Iterator<E> { int cursor; // index of next element to return int lastRet = -1; // index of last element returned; -1 if no such int expectedModCount = modCount; public boolean hasNext() { return cursor != size; } @SuppressWarnings("unchecked") public E next() { checkForComodification(); int i = cursor; if (i >= size) throw new NoSuchElementException(); Object[] elementData = ArrayList.this.elementData; if (i >= elementData.length) throw new ConcurrentModificationException(); cursor = i + 1; return (E) elementData[lastRet = i]; } public void remove() { if (lastRet < 0) throw new IllegalStateException(); checkForComodification(); try { ArrayList.this.remove(lastRet); cursor = lastRet; lastRet = -1; expectedModCount = modCount; } catch (IndexOutOfBoundsException ex) { throw new ConcurrentModificationException(); } } @Override @SuppressWarnings("unchecked") public void forEachRemaining(Consumer<? super E> consumer) { Objects.requireNonNull(consumer); final int size = ArrayList.this.size; int i = cursor; if (i >= size) { return; } final Object[] elementData = ArrayList.this.elementData; if (i >= elementData.length) { throw new ConcurrentModificationException(); } while (i != size && modCount == expectedModCount) { consumer.accept((E) elementData[i++]); } // update once at end of iteration to reduce heap write traffic cursor = i; lastRet = i - 1; checkForComodification(); } final void checkForComodification() { if (modCount != expectedModCount) throw new ConcurrentModificationException(); } }
这部分代码仍是比较简单,大体就是在iterator
方法中返回了一个实例化的Iterator
对象。Itr是一个内部类,它实现了Iterator
接口并实现了其中的方法。
当咱们在使用JAVA开发的时候,想使用迭代器模式的话,只要让咱们本身定义的容器类实现java.util.Iterable
并实现其中的iterator方法使其返回一个java.util.Iterator
的实现类就能够了。
迭代器模式
与集合共生共死的,通常来讲,咱们只要实现一个集合,就须要同时提供这个集合的迭代器,就像java中的Collection,List、Set、Map等,这些集合都有本身的迭代器。假如咱们要实现一个这样的新的容器,固然也须要引入迭代器模式,给咱们的容器实现一个迭代器。但在绝大多数状况,咱们是不须要本身实现的,基本都内置了
优势
缺点
全文代码:https://gitee.com/battcn/design-pattern/tree/master/Chapter14/battcn-iterator
微信公众号:battcn
(欢迎调戏)
关注公众号:battcn
,回复springboot
便可得到 <Spring Boot从入门到实战 基础实战系列教程全集>
与 <2017最新spring boot 外卖实战微信公众平台视频教程>