0x01:迭代器模式简介
Java中可以说已经把迭代器模式用到了极致,每一个集合类都关联了一个迭代器类Iterator。
迭代器模式(Iterator),提供一种方法顺序访问一个聚合对象中的各种元素,而又不暴露该对象的内部表示。UML类图如下:
其中,Aggregate是聚集抽象类,负责提供创建具体迭代器角色的接口;Iterator是迭代抽象类,用于定义得到开始对象、得到下一个对象、判断是否到结尾、当前对象等抽象方法,统一接口;ConcreteAggregate是具体聚集类,继承Aggregate;
ConcreteIterator是具体迭代器类,继承Iterator,实现开始、下一个、是否结尾、当前对象等方法。具体角色说明:
- Iterator(迭代器):迭代器定义访问和遍历元素的接口;
- ConcreteIterator (具体迭代器):具体迭代器实现迭代器接口,对该聚合遍历时跟踪当前位置;
- Aggregate (聚合):聚合定义创建相应迭代器对象的接口;
- ConcreteAggregate (具体聚合):具体聚合实现创建相应迭代器的接口,该操作返回ConcreteIterator的一个适当的实例;
0x02:迭代器模式实现
抽象聚合:负责提供接口,比如定义一个类似createIterator()这样的方法,在Java集合类里一般是iterator()方法。 public interface Aggregate { public void add(Object object); public void remove(Object object); public Iterator iterator(); }
抽象迭代器:负责定义访问和遍历元素的接口,基本上有固定的三个方法,即first()获取第一个元素、next()访问下一个元素、hasNext()判断已经遍历到最后。
public interface Iterator { public Object next(); //遍历到下一个元素 public boolean hasNext(); //是否已经遍历到尾部 public boolean remove(); //删除当前指向的元素 }
具体聚合
public class ConcreteAggregate implements Aggregate { private List list = new ArrayList(); @Override public void add(Object object) { this.list.add(object); } public void remove(Object object) { this.list.remove(object); } @Override public Iterator iterator() { return new ConcreteIterator(this.list); } }
具体迭代器:简单的实现就是通过一个游标,在一个容器中前后移动,遍历所有它需要查看的元素
public class ConcreteIterator implements Iterator { private List list= new ArrayList(); public int cursor = 0; //定义当前游标 public ConcreteIterator(List list) { this.list= list; } @Override public Object next() { Object result = null; if (this.hasNext()) { result = this.list.get(this.cursor); this.cursor = this.cursor + 1; } else { result = null; } return result; } @Override public boolean hasNext() { if (this.cursor == this.list.size()) { return false; } return true; } @Override public boolean remove() { this.list.remove(this.cursor); return true; } }
迭代器模式测试代码
注意引入自己定义的Iterator类,而不是Java内部封装好的java.util.Iterator类。
public class Client { public static void main(String[] args) { Aggregate aggregate = new ConcreteAggregate(); aggregate.add("java乐园"); aggregate.add("架构师知音"); aggregate.add("非常架构"); //遍历 Iterator iterator = aggregate.iterator(); while (iterator.hasNext()) { System.out.println(iterator.next()); } } }
0x03:JDK中的迭代器源码分析
在JDK涉及到的迭代器Iterator都与集合有关,主要相关实现在java.util包下。下面以 ArrayList 为例进行分析:
java.lang.Iterable类:表示一个可以被迭代的对象
public interface Iterable<T> { Iterator<T> iterator(); default void forEach(Consumer<? super T> action) { Objects.requireNonNull(action); for (T t : this) { action.accept(t); } } default Spliterator<T> spliterator() { return Spliterators.spliteratorUnknownSize(iterator(), 0); } }
java.util.Iterator:表示抽象迭代器
public interface Iterator<E> { boolean hasNext(); E next(); default void remove() { throw new UnsupportedOperationException("remove"); } default void forEachRemaining(Consumer<? super E> action) { Objects.requireNonNull(action); while (hasNext()) action.accept(next()); } }
java.util.Collection:表示抽象聚合对象
public interface Collection<E> extends Iterable<E> { Iterator<E> iterator(); boolean add(E e); boolean remove(Object o); boolean addAll(Collection<? extends E> c); boolean removeAll(Collection<?> c); //其他省略 ....... }
java.util.AbstractList.Itr:具体迭代器实现类,该类是 java.util.AbstractList 类的一个内部类
private class ListItr extends Itr implements ListIterator<E> { //具体代码省略 ....... }
java.util.ArrayList:具体聚合对象
public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable { //具体代码省略 ....... }
java.util.ArrayList整体实现UML类图
[来源:https://www.alicharles.com/article/design-pattern/jdk-iterator-pattern/]
研读JDK源码的迭代器模式,可以非常有效的学习和理解迭代器模式。从代码上看JDK的迭代器源码比小编实现的复杂很多,但是基本原理无两。常常研读大神的源码有利于提升技术能力。