Java设计模式(18):迭代器模式

18,迭代器模式(Iterator)

18.1,问题引入_学校体系结构

  • 组合模式 中引入了学校体系结构,并通过 List 集合对各个层级进行定义,可以很方便的对整个结构进行遍历
  • 但是如果各个层级的下属部门集合不一定都是用 List 集合定义,而是通过 Setarray 或者其他自定义方式进行存储,那就没有一个统一的方式进行结构遍历
  • 此时可以引入迭代器模式进行统一

18.2,基本介绍

  • 迭代器模式(Iterator Pattern)是一种常用的设计模式,属于行为型模式
  • 如果我们的集合是通过不同的方式实现的,如Java集合,数组或者自定义集合等,当客户需要遍历这些集合时理论上就需要使用多种遍历方式,而且还会暴露出数据结构的内部规则,此时可以使用迭代器模式进行统一处理
  • 迭代器模式,提供了一种遍历集合的统一接口,用一致的方式遍历元素,不需要知道元素内部数据结构
  • 迭代器模式在Java集合中应用较多

18.3,类图

在这里插入图片描述

  • Department:基础元素类,实体类
  • Iterator:顶层迭代器接口,取自 java.util.Iterator,不需要自行定义,直接从JDK中取即可
  • XXXCollegeIterator:具体迭代器类,对应每一个需要遍历的实体集合,重写迭代器方法,进行元素发现和元素获取
  • College:顶层集合类接口,定义自定义集合的基本方法,并提供统一的获取迭代器方式
  • XXXCollege:具体集合类,重写各自的迭代器获取方式,每一个集合类对应一个迭代器类,各自独立
  • PrintCollege:集合类的管理类,即List<List>,可以对集合类进行统一输出

18.4,代码实现

  • Department:实体类

    package com.self.designmode.iterator;
    
    /**
     * 基础部门对象, 迭代器模式的基础对象
     * @author PJ_ZHANG
     * @create 2020-12-11 17:24
     **/
    public class Department {
    
        private String name;
    
        private String des;
    
        public Department(String name, String des) {
            this.name = name;
            this.des = des;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getDes() {
            return des;
        }
    
        public void setDes(String des) {
            this.des = des;
        }
    
    }
    
  • Iteratorjava.util.Iterator

    package java.util;
    
    import java.util.function.Consumer;
    
    public interface Iterator<E> {
        boolean hasNext();
    
        E next();
    
        default void remove() {
            throw new UnsupportedOperationException("remove");
        }
    
        default void forEachRemaining(Consumer<? super E> var1) {
            Objects.requireNonNull(var1);
    
            while(this.hasNext()) {
                var1.accept(this.next());
            }
    
        }
    }
    
  • ComputerCollegeIterator:计算机学院迭代器类

    package com.self.designmode.iterator;
    
    import java.util.Iterator;
    
    /**
     * 计算机学院迭代器
     * @author PJ_ZHANG
     * @create 2020-12-11 17:25
     **/
    public class ComputerCollegeIterator implements Iterator {
    
        private Department[] departmentArr;
    
        private int index = 0;
    
        public ComputerCollegeIterator(Department[] departmentArr) {
            this.departmentArr = departmentArr;
        }
    
        @Override
        public boolean hasNext() {
            // 如果当前索引以后到最后了, 则条件不成立,返回false
            // 如果数组中有一个元素, 则index = 0 == 1 - 1 = 0, 成立, 可以取第0个
            // 此处if判断不严谨, 没有加数组长度, 说明问题即可
            if (index <= departmentArr.length - 1 && null != departmentArr[index]) {
                return true;
            }
            return false;
        }
    
        @Override
        public Object next() {
            // 取当前元素数据, 并推进索引位置
            return departmentArr[index++];
        }
    }
    
  • InfoCollegeIterator:信息工程学院迭代器类

    package com.self.designmode.iterator;
    
    import java.util.Iterator;
    import java.util.List;
    
    /**
     * 信息工程学院迭代器
     * @author PJ_ZHANG
     * @create 2020-12-11 17:25
     **/
    public class InfoCollegeIterator implements Iterator {
    
        private List<Department> lstDepartment;
    
        private int index = 0;
    
        public InfoCollegeIterator(List<Department> lstDepartment) {
            this.lstDepartment = lstDepartment;
        }
    
        @Override
        public boolean hasNext() {
            // 如果当前索引以后到最后了, 则条件不成立,返回false
            // 如果数组中有一个元素, 则index = 0 == 1 - 1 = 0, 成立, 可以取第0个
            if (index <= lstDepartment.size() - 1) {
                return true;
            }
            return false;
        }
    
        @Override
        public Object next() {
            // 取当前元素数据, 并推进索引位置
            return lstDepartment.get(index++);
        }
    }
    
  • College:学院顶层接口

    package com.self.designmode.iterator;
    
    import java.util.Iterator;
    
    /**
     * 学校顶层接口
     * @author PJ_ZHANG
     * @create 2020-12-11 17:30
     **/
    public interface College {
    
        void addDepartment(Department department);
    
        Iterator iterator();
    
    }
    
  • ComputerCollege:计算机学院

    package com.self.designmode.iterator;
    
    import java.util.Iterator;
    
    /**
     * 计算机学院
     * @author PJ_ZHANG
     * @create 2020-12-11 17:31
     **/
    public class ComputerCollege implements College {
    
        // 构造学院下专业集合
        private Department[] departmentArr;
    
        // 推进索引
        private int index = 0;
    
        public ComputerCollege() {
            departmentArr = new Department[5];
        }
    
        /**
         * 添加专业
         * @param department
         */
        @Override
        public void addDepartment(Department department) {
            departmentArr[index++] = department;
        }
    
        /**
         * 生成计算机学院遍历的迭代器,准备进行遍历
         * @return
         */
        @Override
        public Iterator iterator() {
            return new ComputerCollegeIterator(departmentArr);
        }
    }
    
  • InfoCollege:信息工程学院

    package com.self.designmode.iterator;
    
    import java.util.ArrayList;
    import java.util.Iterator;
    import java.util.List;
    
    /**
     * 信息工程学院
     * @author PJ_ZHANG
     * @create 2020-12-11 17:31
     **/
    public class InfoCollege implements College {
    
        // 构造学院下专业集合
        private List<Department> lstDepartment;
    
        public InfoCollege() {
            lstDepartment = new ArrayList<>(10);
        }
    
        /**
         * 添加专业
         * @param department
         */
        @Override
        public void addDepartment(Department department) {
            lstDepartment.add(department);
        }
    
        /**
         * 生成信息工程学院遍历的迭代器,准备进行遍历
         * @return
         */
        @Override
        public Iterator iterator() {
            return new InfoCollegeIterator(lstDepartment);
        }
    }
    
  • PrintCollege:学院管理类

    package com.self.designmode.iterator;
    
    import java.util.ArrayList;
    import java.util.Iterator;
    import java.util.List;
    
    /**
     * 学院遍历类
     * @author PJ_ZHANG
     * @create 2020-12-11 17:35
     **/
    public class PrintCollege {
    
        private List<College> lstCollege = new ArrayList<>(10);
    
        /**
         * 添加学院对象
         * @param college
         */
        public void addCollege(College college) {
            lstCollege.add(college);
        }
    
        /**
         * 进行遍历
         */
        public void showCollege() {
            for (College college : lstCollege) {
                Iterator iterator = college.iterator();
                showIterator(iterator);
            }
        }
    
        public void showIterator(Iterator iterator) {
            for (;iterator.hasNext();) {
                Department department = (Department) iterator.next();
                System.out.println(department.getName());
            }
        }
    
    }
    
  • Client:客户端

    package com.self.designmode.iterator;
    
    /**
     * 客户端, 进行执行
     * @author PJ_ZHANG
     * @create 2020-12-11 17:38
     **/
    public class Client {
    
        public static void main(String[] args) {
            // 总体展示类
            PrintCollege printCollege = new PrintCollege();
    
            // 构建计算机学院
            ComputerCollege computerCollege = new ComputerCollege();
            computerCollege.addDepartment(new Department("Java专业", "Java专业"));
    
            // 构造信息工程学院
            InfoCollege infoCollege = new InfoCollege();
            infoCollege.addDepartment(new Department("信息工程", "信息工程"));
    
            // 添加学院
            printCollege.addCollege(computerCollege);
            printCollege.addCollege(infoCollege);
            // 展示
            // 注意: 计算机学院使用数组, 信息工程学院使用的是集合
            printCollege.showCollege();
        }
    
    }
    

18.5,迭代器模式的注意事项和细节

  • 提供了统一的元素遍历方式,客户端不用再考虑聚合的类型,通过统一的方式即可遍历
  • 隐藏了聚合的内部结构,客户端进行遍历只能获取到迭代器,隐藏了内部构造
  • 提供了一个设计思想,即一个类中只有一个引起变化的原因(单一职责原则)。在聚合类中,将迭代器分开,就是当管理对象集合和遍历对象集合分开。这样在集合改变的话,只影响聚合对象;遍历方式改变的话,只影响迭代器
  • 当要展示一组相似对象,或者遍历一组相同对象时,需要使用到迭代器模式
  • 缺点:每个聚合对象都需要一个迭代器,则过多的聚合对象势必面临过多的迭代器类,不方便管理。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值