• 行为类模式(四):迭代器(Iterator)


    定义

    提供一种方法访问一个容器(container)对象中的各个元素,而又不暴露该对象的内部细节。

    UML

    优点

    1. 简化了遍历方式,对于对象集合的遍历,还是比较麻烦的,对于数组或者有序列表,我们尚可以通过游标来取得,但用户需要在对集合了解很清楚的前提下,自行遍历对象,但是对于hash表来说,用户遍历起来就比较麻烦了。而引入了迭代器方法后,用户用起来就简单的多了。
    2. 可以提供多种遍历方式,比如说对有序列表,我们可以根据需要提供正序遍历,倒序遍历两种迭代器,用户用起来只需要得到我们实现好的迭代器,就可以方便的对集合进行遍历了。
    3. 封装性良好,用户只需要得到迭代器就可以遍历,而对于遍历算法则不用去关心。

    缺点

    1. 对于比较简单的遍历(像数组或者有序列表),使用迭代器方式遍历较为繁琐,大家可能都有感觉,像ArrayList,我们宁可愿意使用for循环和get方法来遍历集合,操作简易度完爆迭代。

    应用场景

    1. 迭代器模式是与集合共生共死的,一般来说,我们只要实现一个集合,就需要同时提供这个集合的迭代器,就像java中的Collection,List、Set、Map等,这些集合都有自己的迭代器。假如我们要实现一个这样的新的容器,当然也需要引入迭代器模式,给我们的容器实现一个迭代器。
    2. 但是,由于容器与迭代器的关系太密切了,所以大多数语言在实现容器的时候都给提供了迭代器,并且这些语言提供的容器和迭代器在绝大多数情况下就可以满足我们的需要,所以现在需要我们自己去实践迭代器模式的场景还是比较少见的,我们只需要使用语言中已有的容器和迭代器就可以了。

    示例

    考虑这样一个需求,一家大公司合并了一家小公司,而两家公司的工资系统不一样,大公司使用List记录员工工资,小公司使用数组记录员工工资,而这两个不一样的工资系统需要合并进行查询所有人的工资,且需要打印出相同的结果时,我们可以使用迭代器模式来解决这个问题。

    Java

      1 import java.util.ArrayList;
      2 import java.util.List;
      3 
      4 public class Main
      5 {
      6     public static void main(String[] args)
      7     {
      8         //访问集团的工资列表
      9         PayManager payManager = new PayManager();
     10         //先计算再获取
     11         payManager.calcPay();
     12         System.out.println("集团工资列表:");
     13         test(payManager.createIterator());
     14 
     15         //访问新收购公司的工资列表
     16         SalaryManager salaryManager = new SalaryManager();
     17         //先计算再获取
     18         salaryManager.calcSalary();
     19         System.out.println("新收购的公司工资列表:");
     20         test(salaryManager.createIterator());
     21     }
     22 
     23     private static void test(Iterator it)
     24     {
     25         it.first();
     26         while (!it.isDone())
     27         {
     28             Object obj = it.currentItem();
     29             System.out.println("the obj==" + obj);
     30             it.next();
     31         }
     32     }
     33 
     34     /**
     35      * 工资模型
     36      */
     37     public static class PayModel
     38     {
     39         /**
     40          * 支付工资的人员
     41          */
     42         private String userName;
     43 
     44         /**
     45          * 支付的工资数额
     46          */
     47         private double pay;
     48 
     49         public String getUserName()
     50         {
     51             return userName;
     52         }
     53 
     54         public void setUserName(String userName)
     55         {
     56             this.userName = userName;
     57         }
     58 
     59         public double getPay()
     60         {
     61             return pay;
     62         }
     63 
     64         public void setPay(double pay)
     65         {
     66             this.pay = pay;
     67         }
     68 
     69         public String toString()
     70         {
     71             return "userName=" + userName + ", pay=" + pay;
     72         }
     73     }
     74 
     75     /**
     76      * 大公司员工工资管理器
     77      */
     78     public static class PayManager extends Aggregate
     79     {
     80         /**
     81          * 聚合对象,这里是Java的集合对象
     82          */
     83         private List list = new ArrayList();
     84 
     85         public List getPayList()
     86         {
     87             return list;
     88         }
     89 
     90         public void calcPay()
     91         {
     92             PayModel pm1 = new PayModel();
     93             pm1.setPay(3800);
     94             pm1.setUserName("张三");
     95 
     96             PayModel pm2 = new PayModel();
     97             pm2.setPay(5800);
     98             pm2.setUserName("李四");
     99 
    100             list.add(pm1);
    101             list.add(pm2);
    102         }
    103 
    104         public Iterator createIterator()
    105         {
    106             return new CollectionIteratorImpl(this);
    107         }
    108 
    109         public Object get(int index)
    110         {
    111             Object retObj = null;
    112             if (index < this.list.size())
    113             {
    114                 retObj = this.list.get(index);
    115             }
    116             return retObj;
    117         }
    118 
    119         public int size()
    120         {
    121             return this.list.size();
    122         }
    123     }
    124 
    125     /**
    126      * 小公司员工工资管理器
    127      */
    128     public static class SalaryManager extends Aggregate
    129     {
    130         /**
    131          * 用数组管理
    132          */
    133         private PayModel[] pms = null;
    134 
    135         public PayModel[] getPays()
    136         {
    137             return pms;
    138         }
    139 
    140         public void calcSalary()
    141         {
    142             //计算工资,并把工资信息填充到工资列表里面
    143             //为了测试,做点假数据进去
    144             PayModel pm1 = new PayModel();
    145             pm1.setPay(2200);
    146             pm1.setUserName("王五");
    147 
    148             PayModel pm2 = new PayModel();
    149             pm2.setPay(3600);
    150             pm2.setUserName("赵六");
    151 
    152             pms = new PayModel[2];
    153             pms[0] = pm1;
    154             pms[1] = pm2;
    155         }
    156 
    157         public Iterator createIterator()
    158         {
    159             return new ArrayIteratorImpl(this);
    160         }
    161 
    162         public Object get(int index)
    163         {
    164             Object retObj = null;
    165             if (index < pms.length)
    166             {
    167                 retObj = pms[index];
    168             }
    169             return retObj;
    170         }
    171 
    172         public int size()
    173         {
    174             return this.pms.length;
    175         }
    176     }
    177 
    178     /**
    179      * 集合接口
    180      */
    181     public static abstract class Aggregate
    182     {
    183         /**
    184          * 工厂方法,创建相应迭代器对象的接口
    185          * @return 相应迭代器对象的接口
    186          */
    187         public abstract Iterator createIterator();
    188     }
    189 
    190     /**
    191      * 迭代器接口
    192      */
    193     public interface Iterator
    194     {
    195         void first();
    196 
    197         void next();
    198 
    199         boolean isDone();
    200 
    201         Object currentItem();
    202     }
    203 
    204     /**
    205      * 数组迭代器
    206      */
    207     public static class ArrayIteratorImpl implements Iterator
    208     {
    209         /**
    210          * 用来存放被迭代的聚合对象
    211          */
    212         private SalaryManager aggregate = null;
    213 
    214         private int index = -1;
    215 
    216         public ArrayIteratorImpl(SalaryManager aggregate)
    217         {
    218             this.aggregate = aggregate;
    219         }
    220 
    221 
    222         @Override
    223         public void first()
    224         {
    225             index = 0;
    226         }
    227 
    228         @Override
    229         public void next()
    230         {
    231             if (index < this.aggregate.size())
    232             {
    233                 index = index + 1;
    234             }
    235         }
    236 
    237         @Override
    238         public boolean isDone()
    239         {
    240             if (index == this.aggregate.size())
    241             {
    242                 return true;
    243             }
    244             return false;
    245         }
    246 
    247         @Override
    248         public Object currentItem()
    249         {
    250             return this.aggregate.get(index);
    251         }
    252     }
    253 
    254     /**
    255      * 集合列表迭代器
    256      */
    257     public static class CollectionIteratorImpl implements Iterator
    258     {
    259         /**
    260          * 用来存放被迭代的聚合对象
    261          */
    262         private PayManager aggregate = null;
    263 
    264         private int index = -1;
    265 
    266         public CollectionIteratorImpl(PayManager aggregate)
    267         {
    268             this.aggregate = aggregate;
    269         }
    270 
    271         @Override
    272         public void first()
    273         {
    274             index = 0;
    275         }
    276 
    277         @Override
    278         public void next()
    279         {
    280             if (index < this.aggregate.size())
    281             {
    282                 index = index + 1;
    283             }
    284         }
    285 
    286         @Override
    287         public boolean isDone()
    288         {
    289             if (index == this.aggregate.size())
    290             {
    291                 return true;
    292             }
    293             return false;
    294         }
    295 
    296         @Override
    297         public Object currentItem()
    298         {
    299             return this.aggregate.get(index);
    300         }
    301     }
    302 }
    View Code
  • 相关阅读:
    Flink安装排坑指南
    Java对类进行XSS过滤
    java.sql.SQLException: 无法转换为内部表示
    Flutter环境搭建
    运行npm命令 TypeError: Cannot read property 'get' of undefined
    利用Xilinx的cordic ip做开方运算
    modelsim脚本化仿真出现的两个错误
    opencv中使用imread()读入的图像,始终为显示为8位深度
    PS端时钟供给PL使用的问题
    Xilinx 使用shift_RAM消耗分布式RAM(LUTRAM)还是BRAM (Block RAM)?
  • 原文地址:https://www.cnblogs.com/hammerc/p/4743801.html
Copyright © 2020-2023  润新知