聊聊Java设计模式-迭代器模式

简介: 迭代器(Iterator)模式,也叫做游标(Cursor)模式。我们知道,在Java 容器中,为了提高容器遍历的方便性,我们利用迭代器把遍历逻辑从不同类型的集合类中抽取出来,从而避免向外部暴露集合容器的内部结构。

迭代器(Iterator)模式,也叫做游标(Cursor)模式。我们知道,在Java 容器中,为了提高容器遍历的方便性,我们利用迭代器把遍历逻辑从不同类型的集合类中抽取出来,从而避免向外部暴露集合容器的内部结构。

一、迭代器模式介绍

迭代器模式也就是提供一个对象来顺序访问聚合对象中的一系列数据,而不暴露聚合对象的内部表示。它是一种行为型模式,下面就来看看迭代器模式的结构:

1.1 迭代器模式的结构

迭代器模式的结构很简单,就是将聚合对象中的遍历行为分离,并抽象成迭代器类来实现:

image-20220406161104154

  • Aggregate:抽象聚合接口,定义对聚合对象的一些操作和创建迭代器对象的接口
  • Iterator:抽象迭代器接口,定义访问和遍历聚合元素的接口
  • Aggregate1:具体聚合实现,实现抽象聚合接口,返回一个具体迭代器实例对象
  • Iterator1:具体迭代器实现,实现抽象迭代器接口中所定义的方法

1.2 迭代器模式的实现

根据上面的类图,可以实现如下代码:

/**
 * @description: 抽象聚合接口
 * @author: wjw
 * @date: 2022/4/6
 */
public interface Aggregate {
    /**
     * 增加对象
     * @param obj 对象
     */
    void add(Object obj);

    /**
     * 移除对象
     * @param obj 对象
     */
    void remove(Object obj);

    /**
     * 调用迭代器
     * @return 迭代器
     */
    Iterator getIterator();
}

/**
 * @description: 具体迭代器类
 * @author: wjw
 * @date: 2022/4/6
 */
public class Aggregate1 implements Aggregate{

    private List<Object> list = new ArrayList<>();

    @Override
    public void add(Object obj) {
        list.add(obj);
    }

    @Override
    public void remove(Object obj) {
        list.remove(obj);
    }

    @Override
    public Iterator getIterator() {
        return new Iterator1(list);
    }
}
/**
 * @description: 抽象迭代器
 * @author: wjw
 * @date: 2022/4/6
 */
public interface Iterator {

    /**
     * 调用第一个对象
     * @return 对象
     */
    Object first();

    /**
     * 调用下一个对象
     * @return 对象
     */
    Object next();

    /**
     * 迭代器中是否还有下一个对象
     * @return
     */
    boolean hasNext();

}

/**
 * @description: 具体迭代器类
 * @author: wjw
 * @date: 2022/4/6
 */
public class Iterator1 implements Iterator{

    private List<Object> list = null;
    private int index = -1;

    public Iterator1(List<Object> list) {
        this.list = list;
    }

    @Override
    public Object first() {
        index = 0;
        Object obj = list.get(index);
        return obj;
    }

    @Override
    public Object next() {
        Object obj = null;
        if (this.hasNext()) {
            obj = list.get(++index);
        }
        return obj;
    }

    @Override
    public boolean hasNext() {
        if (index < list.size() - 1) {
            return true;
        } else {
            return false;
        }
    }
}
/**
 * @description: 客户端类
 * @author: wjw
 * @date: 2022/4/6
 */
public class Client {
    public static void main(String[] args) {
        Aggregate1 aggregate1 = new Aggregate1();
        aggregate1.add("A");
        aggregate1.add("B");
        aggregate1.add("C");
        System.out.println("聚合对象有:");
        Iterator iterator = aggregate1.getIterator();
        while (iterator.hasNext()) {
            Object obj = iterator.next();
            System.out.println(obj.toString());
        }
        Object first = iterator.first();
        System.out.println("第一个聚合对象是:" + first.toString());
    }
}

客户端测试场结果为:

聚合对象有:
A
B
C
第一个聚合对象是:A

二、迭代器模式的应用场景

2.1 Java 集合容器

Java 集合容器中的使用就是容器中的迭代器了,以ArrayList为例,ArrayList是继承Collection的:

image-20220406193326506

我们发现ArrayList类里面实现迭代器接口的内部类:

image-20220406192935330

其中Itr实现IteratorListItr继承Itr并实现ListIteratorListIteratorIterator功能的扩展。所以实际上ArrayList是抽象聚合和抽象迭代器两者的具体实现,可以画出大致结构图如下:

image-20220406194540279

举个使用ArrayList的例子:

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);
    }
}

输出结果:

ArrayList中的聚合对象为:
A
B
C

在日常业务的开发中,迭代器模式使用的场景并不多,下面就来看看关于迭代器的实战

三、迭代器模式实战

在本案例中模拟迭代遍历输出公司中树形结构的组织结构关系中雇员列表:

公司案例

利用迭代器模式实现的结构如下:

image-20220406200217207

上面结构是以Java容器中迭代器模式基础构建的,左边是迭代器的定义,右边是实现的迭代器功能。具体代码结构图如下:

├─src
│  ├─main
│  │  ├─java
│  │  │  ├─group
│  │  │  │      Employee.java
│  │  │  │      GroupStructure.java
│  │  │  │      Link.java
│  │  │  │
│  │  │  └─lang
│  │  │          Collection.java
│  │  │          Iterable.java
│  │  │          Iterator.java
│  │  │
│  │  └─resources
│  └─test
│      └─java
│              ApiTest.java

对于lang包下是迭代器实现部分,具体代码如下:

/**
 * @description: 可迭代接口定义
 * @author: wjw
 * @date: 2022/4/6
 */
public interface Iterator<E> {

    boolean hasNext();

    E next();
}
/**
 * @description:
 * @author: wjw
 * @date: 2022/4/6
 */
public interface Iterable<E> {

    Iterator<E> iterator();
}
/**
 * @description: 集合功能接口
 * @author: wjw
 * @date: 2022/4/6
 */
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);

    /**
     * 继承Iterable接口的方法
     * @return Iterator
     */
    @Override
    Iterator<E> iterator();
}

group包下是组织结构以及聚类对象及其实现,具体代码如下所示:

/**
 * @description: 雇员类
 * @author: wjw
 * @date: 2022/4/6
 */
public class Employee {

    private String uId;
    private String name;
    private String desc;

    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;
    }
}
/**
 * @description: 树节点链路
 * @author: wjw
 * @date: 2022/4/6
 */
public class Link {

    private String fromId;
    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;
    }
}
/**
 * @description: 迭代器功能实现
 * @author: wjw
 * @date: 2022/4/6
 */
public class GroupStructure implements Collection<Employee, Link> {

    /**组织ID*/
    private String groupId;

    /**组织名称*/
    private String groupName;

    /**雇员列表*/
    private Map<String, Employee> employeeMap = new ConcurrentHashMap<>();

    /**组织架构关系*/
    private Map<String, List<Link>> linkMap = new ConcurrentHashMap<>();

    /**反向关系链*/
    private 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 employee) {
        return null != employeeMap.remove(employee.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>() {

            HashMap<String, Integer> keyMap = new HashMap<>();
            int totalIdx = 0;
            //雇员ID,From
            private String fromId = groupId;
            //雇员ID,To
            private String toId = groupId;

            @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;
            }
        };
    }
}

最后是测试类及其结果:

/**
 * @description: 单元测试类
 * @author: wjw
 * @date: 2022/4/6
 */
public class ApiTest {

    private Logger logger = LoggerFactory.getLogger(ApiTest.class);

    @Test
    public void test_iterator() {
        GroupStructure groupStructure = new GroupStructure("1", "ethan");
        groupStructure.add(new Employee("2", "花花", "二级部门"));
        groupStructure.add(new Employee("3", "豆包", "二级部门"));
        groupStructure.add(new Employee("4", "蹦蹦", "三级部门"));
        groupStructure.add(new Employee("5", "大烧", "三级部门"));
        groupStructure.add(new Employee("6", "虎哥", "四级部门"));
        groupStructure.add(new Employee("7", "玲姐", "四级部门"));
        groupStructure.add(new Employee("8", "秋雅", "四级部门"));

        //添加节点链接
        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();
            logger.info("{},雇员 Id: {} Name: {}", employee.getDesc(), employee.getuId(), employee.getName());
        }
    }
}
21:50:11.087 [main] INFO  ApiTest - 二级部门,雇员 Id: 2 Name: 花花
21:50:11.089 [main] INFO  ApiTest - 三级部门,雇员 Id: 4 Name: 蹦蹦
21:50:11.089 [main] INFO  ApiTest - 三级部门,雇员 Id: 5 Name: 大烧
21:50:11.089 [main] INFO  ApiTest - 四级部门,雇员 Id: 6 Name: 虎哥
21:50:11.089 [main] INFO  ApiTest - 四级部门,雇员 Id: 7 Name: 玲姐
21:50:11.089 [main] INFO  ApiTest - 四级部门,雇员 Id: 8 Name: 秋雅
21:50:11.089 [main] INFO  ApiTest - 二级部门,雇员 Id: 3 Name: 豆包

参考资料

《重学Java设计模式》

目录
相关文章
|
23天前
|
设计模式 Java 程序员
[Java]23种设计模式
本文介绍了设计模式的概念及其七大原则,强调了设计模式在提高代码重用性、可读性、可扩展性和可靠性方面的作用。文章还简要概述了23种设计模式,并提供了进一步学习的资源链接。
36 0
[Java]23种设计模式
|
7天前
|
设计模式 JavaScript Java
Java设计模式:建造者模式详解
建造者模式是一种创建型设计模式,通过将复杂对象的构建过程与表示分离,使得相同的构建过程可以创建不同的表示。本文详细介绍了建造者模式的原理、背景、应用场景及实际Demo,帮助读者更好地理解和应用这一模式。
|
1月前
|
设计模式 Java 开发者
Kotlin教程笔记(54) - 改良设计模式 - 迭代器模式
本教程详细讲解Kotlin语法,适合希望深入了解Kotlin的开发者。对于快速学习Kotlin的用户,推荐查看“简洁”系列教程。本文重点介绍迭代器模式,通过具体示例展示了如何在Kotlin中实现迭代器模式,包括使用Iterator、Iterable接口及重载iterator运算符的方法。
28 4
|
1月前
|
设计模式 Java Kotlin
Kotlin学习笔记 - 改良设计模式 - 迭代器模式
Kotlin学习笔记 - 改良设计模式 - 迭代器模式
27 2
|
1月前
|
设计模式 Java 开发者
Kotlin教程笔记(54) - 改良设计模式 - 迭代器模式
本教程详细讲解了Kotlin中的迭代器模式,包括如何通过实现Iterator和Iterable接口以及重载iterator运算符来实现可遍历的自定义集合。示例展示了如何创建一个图书集类,并通过不同方式使其支持遍历操作,适合希望深入了解Kotlin迭代器模式的开发者。
29 3
|
11天前
|
设计模式 Java Kotlin
Kotlin教程笔记(54) - 改良设计模式 - 迭代器模式
Kotlin教程笔记(54) - 改良设计模式 - 迭代器模式
19 0
|
1月前
|
设计模式 Java Kotlin
Kotlin教程笔记(54) - 改良设计模式 - 迭代器模式
Kotlin教程笔记(54) - 改良设计模式 - 迭代器模式
30 1
|
1月前
|
设计模式 Java Kotlin
Kotlin教程笔记(54) - 改良设计模式 - 迭代器模式
Kotlin教程笔记(54) - 改良设计模式 - 迭代器模式
26 1
|
1月前
|
设计模式 监控 算法
Java设计模式梳理:行为型模式(策略,观察者等)
本文详细介绍了Java设计模式中的行为型模式,包括策略模式、观察者模式、责任链模式、模板方法模式和状态模式。通过具体示例代码,深入浅出地讲解了每种模式的应用场景与实现方式。例如,策略模式通过定义一系列算法让客户端在运行时选择所需算法;观察者模式则让多个观察者对象同时监听某一个主题对象,实现松耦合的消息传递机制。此外,还探讨了这些模式与实际开发中的联系,帮助读者更好地理解和应用设计模式,提升代码质量。
Java设计模式梳理:行为型模式(策略,观察者等)
|
2月前
|
存储 设计模式 安全
Java设计模式-备忘录模式(23)
Java设计模式-备忘录模式(23)