-- 迭代器模式(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);
}
}
}