迭代器模式定义
迭代器模式,英文名Iterator Pattern,指提供一个对象来顺序访问聚合对象中的一系列数据,而又无须暴露该对象的内部表示。
迭代器模式优缺点
1.迭代器模式优点
- 提供一个统一的方法遍历对象,客户不用再考虑聚合的类型,使用一种方法就可以遍历对象了;
- 隐藏了聚合的内部结构,客户端要遍历聚合的时候只能取到迭代器,而不会知道聚合的具体组成;
- 简化了聚合的接口,通过迭代器来遍历聚合对象;
2.迭代器模式缺点
- 增加新的聚合类就需要增加新的迭代器类,类的个数成对增加,一定程度上增加到了系统维护的复杂性;
- 对于比较简单的遍历,使用迭代器模式显得较为繁琐。
迭代器模式类图
迭代器模式主要包含以下角色,如下图所示:
1.抽象聚合(Aggregate)角色
定义存储、添加、删除聚合对象以及创建迭代器对象的接口。
2.具体聚合(ConcreteAggregate)角色
实现抽象聚合类,返回一个具体迭代器的实例。
3.抽象迭代器(Iterator)角色
定义访问和遍历聚合元素的接口,通常包含 hasNext()、first()、next() 等方法。
4.具体迭代器(Concretelterator)角色
实现抽象迭代器接口中所定义的方法,完成对聚合对象的遍历,记录遍历的当前位置。
迭代器模式类图结构,如下图所示:
迭代器模式案例
最能体现迭代器模式的地方莫过于Java 集合容器,比如大家最熟悉的ArrayList。
ArrayList中迭代器的实现采用的是内部类的形式,如下所示:
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]; }
最重要的方法是hasNext和next
- hasNext:用于判断聚合对象是否存在下一个元素,需要在调用next之前调用;
- next:将下标移至下一个元素,并返回游标所越过的那个元素的引用,也就是获取下一个元素;
ArrayList的iterator()该方法可以直接返回一个该内部类迭代器的实例,得到迭代器实例之后就可以用该迭代器实例对集合进行迭代了。
代码如下所示:
public static void main(String[] args) { ArrayList<String> list = new ArrayList<>(); list.add("A"); list.add("B"); list.add("C"); Iterator<String> iterator = list.iterator(); System.out.println("ArrayList中的聚合对象为:"); while (iterator.hasNext()) { String next = iterator.next(); System.out.println(next); } }
迭代器模式让我们在遍历集合元素的时候无需了解集合内部的实现形式,只要它也同样提供一个返回实现了Iterator接口的迭代器实例的方法即可。
迭代器模式应用
当前展示一组相似对象,或者遍历一组相同对象时使用,适合使用迭代器模式。
陈睿mikechen
10年+大厂架构经验,资深技术专家,就职于阿里巴巴、淘宝、百度等一线互联网大厂。
关注「mikechen」公众号,获取更多技术干货!
后台回复【面试】即可获取《史上最全阿里Java面试题总结》,后台回复【架构】,即可获取《阿里架构师进阶专题全部合集》