由于blog各种垃圾评论太多,而且本人审核评论周期较长,所以懒得管理评论了,就把评论功能关闭,有问题可以直接qq骚扰我

设计模式—迭代器模式

JAVA 西门飞冰 583℃
[隐藏]

1.定义

迭代器模式属于行为模式,提供一种方法访问一个容器对象中各个元素,而又不暴露该对象的内部细节。

如果我们的集合元素是用不同的方式实现的,有数组,还有 java 的集合类,或者还有其他方式,当客户端要遍历这些集合元素的时候就要使用多种遍历方式,而且还会暴露元素的内部结构,可以考虑使用迭代器模式解决。

迭代器模式,提供一种遍历集合元素的统一接口,用一致的方法遍历集合元素,不需要知道集合对象的底层表示,即:不暴露其内部的结构。

2.迭代器结构

image-20220929230548852

3.迭代器案例

需求:模拟一个人才市场的人员添加和遍历操作

迭代器接口:

interface Iterator {
   // 下一条数据(类型为Employee员工类型)
   public Employee next();
   // 判断是否还有下一条数据
   public boolean hasNext();
}

对象容器接口:模拟一个人才市场

interface EmploymentMarket {
    // 新增人员信息(身份证号,名称,年龄,技能)
    public void add(String idno , String name , Integer age , String skill);
    // 移除人员(根据身份证号判断)
    public void remove(String idno);
    // 提供一个迭代器,类型为Iterator
    public Iterator iterator();
}

雇员类:比较简单,标准的实体类

public class Employee {
    private String idno;
    private String name;
    private Integer age;
    private String skill;

    public Employee(String idno, String name, Integer age, String skill) {
        this.idno = idno;
        this.name = name;
        this.age = age;
        this.skill = skill;
    }

    public String getIdno() {
        return idno;
    }

    public void setIdno(String idno) {
        this.idno = idno;
    }

    public String getName() {
        return name;
    }

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

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public String getSkill() {
        return skill;
    }

    public void setSkill(String skill) {
        this.skill = skill;
    }
}

容器实现:人才市场的实现类

public class EmploymentMarketImpl implements EmploymentMarket {
    // 定义四个集合分门别类的存储传入的数据
    List<String> idnoList = new ArrayList();
    List<String> nameList = new ArrayList();
    List<Integer> ageList = new ArrayList();
    List<String> skillList = new ArrayList();
    @Override
    public void add(String idno, String name, Integer age, String skill) {
        synchronized (this) {
            // 如果传入的身份证号之前没有登记过,就对传入的属性进行分类存储
            if(!idnoList.contains(idno)) {
                idnoList.add(idno);
                nameList.add(name);
                ageList.add(age);
                skillList.add(skill);
            }
        }
    }

    @Override
    public void remove(String idno) {
        synchronized (this) {
            // 判断传入的身份证号是否存在,存在则移除
            int idx = idnoList.indexOf(idno);
            if(idx != -1) {
                idnoList.remove(idx);
                nameList.remove(idx);
                ageList.remove(idx);
                skillList.remove(idx);
            }
        }
    }

    @Override
    // 迭代器
    public Iterator iterator() {
        return new EmployeeIterator(idnoList,nameList,ageList,skillList);
    }
}

迭代器实现:封装了遍历和迭代转化的过程

public class EmployeeIterator implements Iterator{
    // 游标:定义数据的前一个值
    int cursor = -1;
    List<String> idnoList ;
    List<String> nameList ;
    List<Integer> ageList ;
    List<String> skillList ;
    // 外侧传入四个构造参数才能实例化构造对象
    public EmployeeIterator(List<String> idnoList,List<String> nameList , List<Integer> ageList,List<String> skillList){
        this.idnoList = idnoList;
        this.nameList = nameList;
        this.ageList = ageList;
        this.skillList = skillList;
    }
    @Override
    // 数据提取过程
    public Employee next() {
        if(hasNext()) {
            // 游标位置向后移动
            ++cursor;
            // 将后一条数据的游标传入每一个list集合中,提取下一条数据每一个值
            Employee employee = new Employee(idnoList.get(cursor), nameList.get(cursor), ageList.get(cursor), skillList.get(cursor));
            return employee;
        }else{
            // 如果没有数据就返回null
            return null;
        }
    }

    @Override
    // 判断是否还有下一个数据
    public boolean hasNext() {
        if(cursor < idnoList.size()-1){
            return true;
        }else {
            return false;
        }
    }
}

客户端:

public class Client {
    public static void main(String[] args) {
        // 创建人才市场实现类,并初始化数据
        EmploymentMarket market = new EmploymentMarketImpl();
        market.add("130102XXXXXXXX0524","张燕",37,"IT产品销售");
        market.add("130104XXXXXXXX1928","李晶",28,"地产策划");
        market.add("130203XXXXXXXX0911","吴宇森",55,"电影导演");

        // 得到迭代器对象
        Iterator iterator = market.iterator();
        // 遍历人才市场相关数据
        while (iterator.hasNext()){
            Employee employee = iterator.next();
            System.out.println(employee);
        }
    }
}

4.迭代器优点

1、简化了遍历⽅式,对于对象集合的遍历,还是⽐较麻烦的,对于数组或者有序列表,我们尚可以通过游标来取得,但⽤户需要在对集合了解很清楚的前提下,⾃⾏遍历对象,但是对于hash表来说,⽤户遍历起来就⽐较麻烦了。⽽引⼊了迭代器⽅法后,⽤户⽤起来就简单的多了。

2、可以提供多种遍历⽅式,⽐如说对有序列表,我们可以根据需要提供正序遍历,倒序遍历两种迭代器,⽤户⽤起来只需要得到我们实现好的迭代器,就可以⽅便的对集合进⾏遍历了。

3、封装性良好,⽤户只需要得到迭代器就可以遍历,⽽对于遍历算法则不⽤去关⼼。

5.迭代器缺点

对于⽐较简单的遍历(像数组或者有序列表),使⽤迭代器⽅式遍历较为繁琐,⼤家可能都有感觉,像ArrayList,我们宁可愿意使⽤for循环和get⽅法来遍历集合。

6.应用场景

Java集合类

复杂的数据结构,对客户端只暴露最简单的Iterator迭代器即可

转载请注明:西门飞冰的博客 » 设计模式—迭代器模式

喜欢 (0)or分享 (0)