第六章 6.6 迭代器模式

分类:01_设计模式

标签:

6.6.1 迭代器模式介绍

迭代器模式是我们学习一个设计时很少用到的、但编码实现时却经常使用到的行为型设计模式。在绝大多数编程语言中,迭代器已经成为一个基础的类库,直接用来遍历集合对象。在平时开发中,我们更多的是直接使用它,很少会从零去实现一个迭代器。

迭代器模式(Iterator pattern)又叫游标(Cursor)模式,它的原始定义是:迭代器提供一种对容器对象中的各个元素进行访问的方法,而又不需要暴露该对象的内部细节。

120.jpg

在软件系统中,容器对象拥有两个职责: 一是存储数据,而是遍历数据.从依赖性上看,前者是聚合对象的基本职责.而后者是可变化的,又是可分离的.因此可以将遍历数据的行为从容器中抽取出来,封装到迭代器对象中,由迭代器来提供遍历数据的行为,这将简化聚合对象的设计,更加符合单一职责原则

6.6.2 迭代器模式原理

迭代器模式结构图

121.jpg

迭代器模式主要包含以下角色:

6.6.3 迭代器模式实现


/**
* 迭代器接口
* @author spikeCong
* @date 2022/10/18
**/
public interface Iterator<E> {

   //判断集合中是否有下一个元素
   boolean hasNext();

   //将游标后移一位元素
   void next();

   //返回当前游标指定的元素
   E currentItem();
}

/**
* 具体迭代器
* @author spikeCong
* @date 2022/10/18
**/
public class ConcreteIterator<E> implements Iterator<E>{

   private int cursor; //游标

   private ArrayList<E> arrayList; //容器

   public ConcreteIterator(ArrayList<E> arrayList) {
       this.cursor = 0;
       this.arrayList = arrayList;
   }

   @Override
   public boolean hasNext() {
       return cursor != arrayList.size();
   }

   @Override
   public void next() {
       cursor++;
   }

   @Override
   public E currentItem() {
       if(cursor >= arrayList.size()){
           throw new NoSuchElementException();
       }
       return arrayList.get(cursor);
   }
}

public class Test01 {


   public static void main(String[] args) {

       ArrayList<String> names = new ArrayList<>();
       names.add("lisi");
       names.add("zhangsan");
       names.add("wangwu");

       Iterator<String> iterator = new ConcreteIterator(names);
       while(iterator.hasNext()){
           System.out.println(iterator.currentItem());
           iterator.next();
       }

       /**
        * 使用ArrayList集合中的iterator()方法获取迭代器
        * 将创建迭代器的方法放入集合容器中,这样做的好处是对客户端封装了迭代器的实现细节.
        */
       java.util.Iterator<String> iterator1 = names.iterator();
       while(iterator1.hasNext()){
           System.out.println(iterator1.next());
           iterator.next();
       }
   }
}

6.6.4 迭代器模式应用实例

为了帮助你更好地理解迭代器模式,下面我们还是通过一个简单的例子给大家演示一下


/**
* 抽象迭代器 IteratorIterator
* @author spikeCong
* @date 2022/10/18
**/
public interface IteratorIterator<E> {

   void reset();   //重置为第一个元素
   E next();   //获取下一个元素
   E currentItem();    //检索当前元素
   boolean hasNext();  //判断是否还有下一个元素存在
}


/**
* 抽象集合 ListList
* @author spikeCong
* @date 2022/10/18
**/
public interface ListList<E> {

   //获取迭代器对象的抽象方法(面向接口编程)
   IteratorIterator<E> Iterator();
}

/**
* 主题类
* @author spikeCong
* @date 2022/10/18
**/
public class Topic {

   private String name;

   public Topic(String name) {
       this.name = name;
   }

   public String getName() {
       return name;
   }

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

/**
* 具体迭代器
* @author spikeCong
* @date 2022/10/18
**/
public class TopicIterator implements IteratorIterator<Topic> {

   //Topic数组
   private Topic[] topics;

   //记录存储位置
   private int position;

   public TopicIterator(Topic[] topics) {
       this.topics = topics;
       position = 0;
   }

   @Override
   public void reset() {
       position = 0;
   }

   @Override
   public Topic next() {
       return topics[position++];
   }

   @Override
   public Topic currentItem() {
       return topics[position];
   }

   @Override
   public boolean hasNext() {
       if(position >= topics.length){
           return false;
       }
       return true;
   }
}

/**
* 具体集合类
* @author spikeCong
* @date 2022/10/18
**/
public class TopicList implements ListList<Topic> {

   private Topic[] topics;

   public TopicList(Topic[] topics) {
       this.topics = topics;
   }

   @Override
   public IteratorIterator<Topic> Iterator() {
       return new TopicIterator(topics);
   }
}

public class Client {

   public static void main(String[] args) {

       Topic[] topics = new Topic[4];
       topics[0] = new Topic("topic1");
       topics[1] = new Topic("topic2");
       topics[2] = new Topic("topic3");
       topics[3] = new Topic("topic4");

       TopicList topicList = new TopicList(topics);
       IteratorIterator<Topic> iterator = topicList.Iterator();

       while(iterator.hasNext()){
           Topic t = iterator.next();
           System.out.println(t.getName());
       }
   }
}

6.6.5 迭代器模式总结

1) 迭代器的优点:

2) 迭代器的缺点:

3) 使用场景


修改内容