美文网首页
迭代器模式,存储数据与遍历数据的分离

迭代器模式,存储数据与遍历数据的分离

作者: 程就人生 | 来源:发表于2022-05-05 20:16 被阅读0次

    你是否每次要遍历一个集合时,总是若有所思?

    集合的遍历,是怎么迭代的来?有没有通用法则?

    你有没有想过,自己来实现一个迭代器?



    迭代器模式(Iterator Pattern),是一种顺序访问聚合对象的行为型模式,它把存储数据和遍历数据进行了解耦。使用户不必关心集合对象的底层表示,即可顺序地访问集合中的对象。

    业务场景:需要把存储数据和遍历数据分开处理的场合。

    关键代码:hasNext和next;hasNext表示还有没有下一个对象;next则表示访问下一个对象。

    下面看UML类图:


    UML类图说明:IIterator负责数据遍历,IContainer负责数据存储,NameRepository又聚合了NameIterator,关系非常简单。

    代码实现步骤:

    1. 迭代器接口;
    /**
     * 1.遍历接口
     * @author 程就人生
     * @Date
     */
    public interface IIterator<T> {
      // 还有没有下一个元素
      public boolean hasNext();
      // 读取下一个元素
      public T next();
    }
    

    2.容器接口;

    /**
     * 2.容器接口
     * @author 程就人生
     * @Date
     */
    public interface IContainer<T> {
      // 迭代集合中所有的元素
      public IIterator<T> getIterator();
    }
    

    3.容器实现类;

    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * 3.容器实现类
     * @author 程就人生
     * @Date
     */
    public class NameRepository implements IContainer<String>{
      
      private List<String> nameList;
      
      public NameRepository(){
        nameList = new ArrayList<String>();
      }
      
      public void add(String name){
        nameList.add(name);
      }
    
      @Override
      public IIterator<String> getIterator() {
        return new NameIterator(nameList);
      }
    }
    

    4.迭代器实现类;

    import java.util.List;
    
    /**
     * 4. 遍历数据的具体实现
     * @author 程就人生
     * @Date
     */
    public class NameIterator implements IIterator<String>{
      
      private int index;
      
      private List<String> nameList;
      
      public NameIterator(List<String> nameList){
        this.nameList =nameList;
      }
    
      @Override
      public boolean hasNext() {
        // 有则返回true,否则返回false
        if(nameList != null && index < nameList.size()){
          return true;
        }
        return false;
      }
    
      @Override
      public String next() {
        if(this.hasNext()){
          return nameList.get(index++);
        }
        return null;
      }  
    }
    

    也可以把迭代器作为容器实现类的内部类来实现;

    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * 3.NameRepository实现了容器接口
     * @author 程就人生
     * @Date
     */
    public class NameRepository implements IContainer<String>{
      private static List<String> nameList;
      public NameRepository(){
        nameList = new ArrayList<String>();
      }
      
      public void add(String name){
        nameList.add(name);
      }
      
      @Override
      public IIterator<String> getIterator() {
        return new NameIterator();
      }
      
      /**
       * 3.1 内部类实现了遍历接口,遍历数据的具体实现
       * @author 程就人生
       * @Date
       */
      private class NameIterator implements IIterator<String>{    
        private int index;
        @Override
        public boolean hasNext() {
          if(nameList != null && index < nameList.size()){
            return true;
          }
          return false;
        }
        @Override
        public String next() {
          if(this.hasNext()){
            return nameList.get(index++);
          }
          return null;
        }    
      }
    }
    

    5.测试代码;

    public static void main(String[] argo){ 
        NameRepository nameRepository = new NameRepository();
        // 数据存储
        nameRepository.add("张三");
        nameRepository.add("王五");
        nameRepository.add("李四");
        
        // 数据遍历,存在下一个时,则打印下一个对象    
        for(IIterator<String> iterator = nameRepository.getIterator(); iterator.hasNext();){
          System.out.println(iterator.next());
        }
      }
    }
    

    测试结果:

    张三
    王五
    李四
    

    这段代码的意思是:创建一个动态存储名称的容器NameRepository,其中NameIterator类通过hasNext判断是否还有下一个元素,通过Next获取下一个元素,如此循环,直至把聚合对象中的元素全部遍历完毕。

    NameIterator即可作为一个单独的类处理,又可聚合到NameRepository对象里面,作为该对象的内部类使用。至此,一个简单的迭代器模式编码完成。

    最后总结

    迭代器模式,主要负责存储数据和遍历数据的分离。它是一种很好理解,又经常使用的行为型模式。

    思考题:列举一下在项目中,各种集合的遍历是如何实现的吧!

    相关文章

      网友评论

          本文标题:迭代器模式,存储数据与遍历数据的分离

          本文链接:https://www.haomeiwen.com/subject/hsxyyrtx.html