Java - 迭代器模式

-- 迭代器模式(Iterator)这种模式用于顺序访问集合对象的元素,不需要知道集合对象的底层表示。

大概就是分离了集合对象的遍历行为,抽象出一个迭代器类来负责,这样既可以做到不暴露集合的内部结构,又可让外部代码透明地访问集合内部的数据。

一、使用场景: 

  • 访问一个聚合(集合)对象的内容而无须暴露它的内部表示。
  • 需要为聚合(集合)对象提供多种遍历方式。

如果以上场景不使用,会存在如下问题:

  • 如果让调用者自己实现遍历,会直接暴露数据细节给外部。

Java已有许多实现好的类似栗子 - 集合框架里的集合(List,Set等等),它们原理都是数组存储,都实现了迭代器。

下面我们也手动实现一个属于自己的集合

二、模式结构:

官方结构图 :

组成(角色) 作用
Aggregate (聚合抽象类) 提供集合容器,和获取迭代器的方法
ConcreteAggregate (具体聚合类) 聚合对象,实现获取迭代器方法
Iterator(迭代器抽象类) 这里java jdk 有提供,我们无需提供该接口
ConcreteIterator (具体迭代器抽象类) 这里一般作为内部类(外部类也可以),在具体聚合类实现

三、栗子《模仿javaList 定义一个属于自己的集合(简易版)》

1、Aggregate 聚合抽象类 

- 作为聚合容器接口仅提供获取迭代器的抽象方法

package com.behavior.iterator;

import java.util.Iterator;

/**
 * @description: 集合容器
 * @author: ziHeng
 * @create: 2018-08-14 11:59
 **/
public interface CollectionContainer {

    //提供获取迭代器抽象方法
    Iterator getIterator();

}

2、ConcreteAggregate具体聚合类 

- 外部类实现聚合抽象类,内部类实现 java.util.Iterator 接口

package com.behavior.iterator;

import java.util.Iterator;

/**
 * @description: 自定义学生集合
 * @author: ziHeng
 * @create: 2018-08-13 23:30
 **/
public class StudentCollection implements CollectionContainer {

    //默认数组最大长度
    private int defaultLength = 2;

    //学生数组
    private Object[] students =new Object[defaultLength];

    //数组实际
    private int size = 0;


    //添加学生方法
    public void addStudent(Student student){
        students[size++]=student;

        //当达到了长度,需要扩展组数最大长度
        if(size >= defaultLength){
            //左移 数组长度扩大一倍
            defaultLength=defaultLength<<1;
            Object[] target = new Object[defaultLength];
            //数组复制 参数顺序:1、原始数组,2、原始数组偏移量,3、目标数组,4、目标数组偏移量,5、复制的长度
            System.arraycopy(students,0,target,0,size);
            students=target;
        }
    }

    //删除学生
    public void deleteStudent(Student student){
        //数据结构
        int length = size;
        for (int i = 0; i < length; i++) {
            if(student== students[i]){
                for (int j = i; j < length; j++) {
                    students[j]= students[j+1];
                }
                students[length-1]=null;
            }
        }
        //数组下标索引
        size--;
    }

    @Override
    //实现获取迭代器方法
    public Iterator getIterator(){
        return new StudentIterator();
    }

    private class StudentIterator implements Iterator{

        //索引
        private int index;

        @Override
        public boolean hasNext() {
            return index < size;
        }

        @Override
        public Object next() {
            return students[index++];
        }
    }



}

3、Student实体类

package com.behavior.iterator;

import lombok.Data;

/**
 * @description: 学生
 * @author: ziHeng
 * @create: 2018-08-13 23:29
 **/
@Data  //lombok插件
public class Student {

    private int id;

    private String name;

    public Student(int id, String name) {
        this.id = id;
        this.name = name;
    }
}

调用Test测试:

package com.behavior.iterator;

import java.util.Iterator;

/**
 * @description: 迭代模式测试
 * @author: ziHeng
 * @create: 2018-08-13 22:43
 **/
public class IteratorTest {

    public static void main(String[] args) {
        Student student1 = new Student(1,"张一");
        Student student2 = new Student(2,"李二");
        Student student3 = new Student(3,"王三");


        StudentCollection studentCollection = new StudentCollection();
        studentCollection.addStudent(student1);
        studentCollection.addStudent(student2);
        studentCollection.addStudent(student3);

        studentCollection.deleteStudent(student2);

        Iterator iterator = studentCollection.getIterator();
        while (iterator.hasNext()){
            Object next = iterator.next();
            System.out.println(next);
        }
    }

}

猜你喜欢

转载自blog.csdn.net/weixin_39569611/article/details/81664017