被用到炉火纯清的迭代器模式

简介: 迭代器模式(Iterator),提供一种方法顺序访问一个聚合对象中的各种元素,而又不暴露该对象的内部表示。

0x01:迭代器模式简介


Java中可以说已经把迭代器模式用到了极致,每一个集合类都关联了一个迭代器类Iterator。


迭代器模式(Iterator),提供一种方法顺序访问一个聚合对象中的各种元素,而又不暴露该对象的内部表示。UML类图如下:


微信图片_20220502085927.png


其中,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类图


微信图片_20220502085939.png


[来源:https://www.alicharles.com/article/design-pattern/jdk-iterator-pattern/]


研读JDK源码的迭代器模式,可以非常有效的学习和理解迭代器模式。从代码上看JDK的迭代器源码比小编实现的复杂很多,但是基本原理无两。常常研读大神的源码有利于提升技术能力。


相关文章
|
3月前
|
设计模式 安全 Java
Java设计模式-迭代器模式(21)
Java设计模式-迭代器模式(21)
|
7月前
|
设计模式 uml C++
行为型 迭代器模式
行为型 迭代器模式
45 0
|
设计模式 存储 算法
设计模式~迭代器模式(Iterator)-20
迭代器模式(Iterator Pattern)是Java和.Net编程环境中非常常用的设计模式。这种模式用于顺序访问集合对象的元素,不需要知道集合对象的底层表示。迭代器模式属于行为型模式。迭代器模式已经被淘汰,java中已经把迭代器运用到各个聚集类(collection)中了,使用java自带的迭代器就已经满足我们的需求了 目录 迭代器模式(Iterator) (1)优点 (2)缺点 (3)使用场景 (4)注意事项 (5)应用实例: 代码
60 0
|
设计模式 存储 Java
迭代器模式
迭代器模式(Iterator Pattern)是一种行为型设计模式,它提供了一种顺序访问聚合对象中每个元素的方法,而不暴露其内部实现。
104 1
|
容器
关于迭代器模式我所知道的
关于迭代器模式我所知道的
56 0
|
设计模式 Java 索引
Java设计模式-迭代器模式(Iterator)
Java设计模式-迭代器模式(Iterator)
|
JavaScript 前端开发
简单理解迭代器模式
这几天研究了一下迭代器模式,期间有一段时间经常搞不太懂一些概念与概念之间的关系,今天来整理一下。
132 0
|
设计模式 存储 容器
我学会了,迭代器模式
迭代器模式属于行为型模式,这个类型的设计模式总结出了 类、对象之间的经典交互方式,将类、对象的行为和使用解耦了,花式的去使用对象的行为来完成特定场景下的功能。
104 0
我学会了,迭代器模式
|
Java 容器
迭代器模式
迭代器模式
115 0
|
设计模式 存储 Java
迭代器模式:理解与实践
上面的这段代码通过循环逐一将arr的下标加1,从而实现了遍历数组的功能。 但是通过循环实现遍历的话依赖于集合对象内部,因此就有了一种能顺序访问集合对象中各个元素,又无需依赖对象内部表示的设计模式--迭代器模式。