迭代器模式(Iterator Pattern)

Posted 顧棟

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了迭代器模式(Iterator Pattern)相关的知识,希望对你有一定的参考价值。

迭代器模式(Iterator Pattern)

迭代器模式的定义

它提供一种方法访问一个容器对象中各个元素,而又不需暴露该对象的内部细节。迭代器是为容器服务的,那什么是容器呢? 能容纳对象的所有类型都可以称之为容。例如Collection集合类型、Set类型等,迭代器模式就是为解决遍历这些容器中的元素而诞生的。

迭代器模式的优点

  1. 访问一个聚合对象的内容而无须暴露它的内部表示。
  2. 遍历任务交由迭代器完成,这简化了聚合类。
  3. 它支持以不同方式遍历一个聚合,甚至可以自定义迭代器的子类以支持新的遍历。
  4. 增加新的聚合类和迭代器类都很方便,无须修改原有代码。
  5. 封装性良好,为遍历不同的聚合结构提供一个统一的接口。

迭代器模式的缺点

  1. 增加了类的个数,这在一定程度上增加了系统的复杂性。

迭代器模式的结构

  1. 抽象聚合(Aggregate)角色:抽象容器,定义存储、添加、删除聚合对象以及创建迭代器对象的接口,必然提供一个类似createIterator()这样的
    方法,在Java中一般是iterator()方法。
  2. 具体聚合(ConcreteAggregate)角色:具体容器,实现抽象聚合类,返回一个具体迭代器的实例。
  3. 抽象迭代器(Iterator)角色:定义访问和遍历聚合元素的接口,通常包含 hasNext()、first()、next() 等方法。
  4. 具体迭代器(Concretelterator)角色:实现抽象迭代器接口中所定义的方法,完成对聚合对象的遍历,记录遍历的当前位置。

迭代器模式的实现

一般实现

/**
 * 抽象迭代器
 */
public interface Iterator {
    /**
     * 遍历到下一个元素
     */
    public Object next();

    /**
     * 是否已经遍历到尾部
     */
    public boolean hasNext();

    /**
     * 删除当前指向的元素
     */
    public boolean remove();
}
/**
 * 具体迭代器
 */
public class ConcreteIterator implements Iterator {
    private Vector vector = new Vector();
    /**
     * 定义当前游标
     */
    public int cursor = 0;

    @SuppressWarnings("unchecked")
    public ConcreteIterator(Vector vector) {
        this.vector = vector;
    }

    /**
     * 遍历到下一个元素
     */
    @Override
    public Object next() {
        Object result = null;
        if (this.hasNext()) {
            result = this.vector.get(this.cursor++);
        }
        return result;
    }

    /**
     * 是否已经遍历到尾部
     */
    @Override
    public boolean hasNext() {
        return this.cursor != this.vector.size();
    }

    /**
     * 删除当前指向的元素
     */
    @Override
    public boolean remove() {
        this.vector.remove(this.cursor);
        return true;
    }
}
/**
 * 抽象容器
 */
public interface Aggregate {
    /**
     * 是容器必然有元素的增加
     */
    public void add(Object object);

    /**
     * 减少元素
     */
    public void remove(Object object);

    /**
     * 由迭代器来遍历所有的元素
     */
    public Iterator iterator();
}
/**
 * 具体容器
 */
public class ConcreteAggregate implements Aggregate {
    /**
     * 容纳对象的容器
     */
    private Vector vector = new Vector();

    /**
     * 是容器必然有元素的增加
     *
     * @param object
     */
    @Override
    public void add(Object object) {
        this.vector.add(object);
    }

    /**
     * 减少元素
     *
     * @param object
     */
    @Override
    public void remove(Object object) {
        this.vector.remove(object);
    }

    /**
     * 由迭代器来遍历所有的元素
     */
    @Override
    public Iterator iterator() {
        return new ConcreteIterator(this.vector);
    }
}
public static void main(String[] args) {
    //声明出容器
    Aggregate agg = new ConcreteAggregate();
    //产生对象数据放进去
    agg.add("abc");
    agg.add("aaa");
    agg.add("1234");
    //遍历一下
    Iterator iterator = agg.iterator();
    while (iterator.hasNext()) {
        System.out.println(iterator.next());
    }
    agg.remove("aaa");
     iterator = agg.iterator();
    while (iterator.hasNext()) {
        System.out.println(iterator.next());
    }
}

参考JDK实现数遍历

/**
 * 迭代器
 */
public interface Iterator<E> {
    boolean hasNext();

    E next();
}
/**
 * 可迭代接口
 */
public interface Iterable<E> {

    Iterator<E> iterator();

}
/**
 * 集合功能接口定义
 */
public interface Collection<E, L> extends Iterable<E> {

    boolean add(E e);

    boolean remove(E e);

    boolean addLink(String key, L l);

    boolean removeLink(String key);

    @Override
    Iterator<E> iterator();

}
/**
 * 雇员
 */
public class Employee {
    /**
     * ID
     */
    private String uId;
    /**
     * 姓名
     */
    private String name;
    /**
     * 备注
     */
    private String desc;

    public Employee(String uId, String name) {
        this.uId = uId;
        this.name = name;
    }

    public Employee(String uId, String name, String desc) {
        this.uId = uId;
        this.name = name;
        this.desc = desc;
    }

    public String getuId() {
        return uId;
    }

    public void setuId(String uId) {
        this.uId = uId;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getDesc() {
        return desc;
    }

    public void setDesc(String desc) {
        this.desc = desc;
    }

}
/**
 * 树节点链路
 */
public class Link {
    /**
     * 雇员fromId
     */
    private String fromId;
    /**
     * 雇员ID
     */
    private String toId;

    public Link(String fromId, String toId) {
        this.fromId = fromId;
        this.toId = toId;
    }

    public String getFromId() {
        return fromId;
    }

    public void setFromId(String fromId) {
        this.fromId = fromId;
    }

    public String getToId() {
        return toId;
    }

    public void setToId(String toId) {
        this.toId = toId;
    }

}
/**
 * (核⼼)迭代器功能实现
 */
public class GroupStructure implements Collection<Employee, Link> {

    /**
     * 组织ID,也是一个组织链的头部ID
     */
    private final String groupId;
    /**
     * 组织名称
     */
    private String groupName;
    /**
     * 雇员列表
     */
    private final Map<String, Employee> employeeMap = new ConcurrentHashMap<>();
    /**
     * 组织架构关系;id->list
     */
    private final Map<String, List<Link>> linkMap = new ConcurrentHashMap<>();
    /**
     * 反向关系链
     */
    private final Map<String, String> invertedMap = new ConcurrentHashMap<>();

    public GroupStructure(String groupId, String groupName) {
        this.groupId = groupId;
        this.groupName = groupName;
    }

    @Override
    public boolean add(Employee employee) {
        return null != employeeMap.put(employee.getuId(), employee);
    }

    @Override
    public boolean remove(Employee o) {
        return null != employeeMap.remove(o.getuId());
    }

    @Override
    public boolean addLink(String key, Link link) {
        invertedMap.put(link.getToId(), link.getFromId());
        if (linkMap.containsKey(key)) {
            return linkMap.get(key).add(link);
        } else {
            List<Link> links = new LinkedList<>();
            links.add(link);
            linkMap.put(key, links);
            return true;
        }
    }

    @Override
    public boolean removeLink(String key) {
        return null != linkMap.remove(key);
    }

    @Override
    public Iterator<Employee> iterator() {

        return new Iterator<Employee>() {

            final HashMap<String, Integer> keyMap = new HashMap<>();

            int totalIdx = 0;
            private String fromId = groupId;  // 雇员ID,From
            private String toId = groupId;   // 雇员ID,To

            @Override
            public boolean hasNext() {
                return totalIdx < employeeMap.size();
            }

            @Override
            public Employee next() {
                List<Link> links = linkMap.get(toId);
                int cursorIdx = getCursorIdx(toId);

                // 同级节点扫描
                if (null == links) {
                    cursorIdx = getCursorIdx(fromId);
                    links = linkMap.get(fromId);
                }

                // 上级节点扫描
                while (cursorIdx > links.size() - 1) {
                    fromId = invertedMap.get(fromId);
                    cursorIdx = getCursorIdx(fromId);
                    links = linkMap.get(fromId);
                }

                // 获取节点
                Link link = links.get(cursorIdx);
                toId = link.getToId();
                fromId = link.getFromId();
                totalIdx++;

                // 返回结果
                return employeeMap.get(link.getToId());
            }

            public int getCursorIdx(String key) {
                int idx = 0;
                if (keyMap.containsKey(key)) {
                    idx = keyMap.get(key);
                    keyMap.put(key, ++idx);
                } else {
                    keyMap.put(key, idx);
                }
                return idx;
            }
        };

    }
}
public static void main(String[] args) {
    GroupStructure groupStructure = new GroupStructure("1", "组织");
    groupStructure.add(new Employee("2", "员工1", "二级部门"));
    groupStructure.add(new Employee("3", "员工2", "二级部门"));
    groupStructure.add(new Employee("4", "员工3", "三级部门"));
    groupStructure.add(new Employee("5", "员工4", "三级部门"));
    groupStructure.add(new Employee("6", "员工6", "四级部门"));
    groupStructure.add(new Employee("7", "员工5", "四级部门"));
    groupStructure.add(new Employee("8", "员工7", "四级部门"));

    groupStructure.addLink("1", new Link("1", "2"));
    groupStructure.addLink("1", new Link("1", "3"));

    groupStructure.addLink("2", new Link("2", "4"));
    groupStructure.addLink("2", new Link("2", "5"));

    groupStructure.addLink("5", new Link("5", "6"));
    groupStructure.addLink("5", new Link("5", "7"));
    groupStructure.addLink("5", new Link("5", "8"));

    Iterator<Employee> iterator = groupStructure.iterator();
    while (iterator.hasNext()) {
        Employee employee = iterator.next();
        System.out.println(employee.getDesc() + ",雇员 Id:" + employee.getuId() + " Name:" + employee.getName());
    }
}

适用场景

  1. 当需要为聚合对象提供多种遍历方式时。
  2. 当需要为遍历不同的聚合结构提供一个统一的接口时。
  3. 当访问一个聚合对象的内容而无须暴露其内部细节的表示时。

本文主要参考:

  1. 小傅哥的《重学Java模式》
  2. 《C语言中文网》设计模式的相关内容
  3. 《设计模式之禅》第二版 秦小波

以上是关于迭代器模式(Iterator Pattern)的主要内容,如果未能解决你的问题,请参考以下文章

迭代器模式(Iterator Pattern)

设计模式 - 迭代器模式(iterator pattern) 具体解释

迭代器模式(Iterator Pattern)

17迭代器模式(Iterator Pattern)

java设计模式行为模式Behavioral Pattern迭代器模式Iterator Pattern

尚硅谷设计模式学习(17)---[迭代器模式(Iterator Pattern)]