什么是迭代器模式(Iterator)
概念
迭代器(Iterator)模式属于行为型模式,定义:提供一个迭代器来顺序访问聚合对象(聚合对象内部存储着其他对象,这些对象和聚合对象不一定是同生共死的关系)中的一系列数据,而不暴露聚合对象的内部表示。也就是实现聚合数据和遍历算法的分离,如果把数据和遍历算法都放到一个类中,首先这个类会变得非常臃肿,其次如果想更换遍历算法,就得修改代码了。
一般情况下,只有在设计数据结构时才会使用迭代器模式,Java已经为我们定义好了非常多的数据结构, Collection、List、Set、Map,这些类中都是包含着迭代器的,我们可以通过iterator()方法来获取,当然我们也可以再去实现自己想要的迭代器。
优点
- 保护了聚合类内部的数据。使用迭代器就无需暴露聚合对象内部的结构。
- 简化了数据的访问方式。
- 支持使用不同的方式遍历聚合,可以定义新的迭代器。
- 提高了聚合类的封装性。
- 符合单一职责原则。迭代器负责处理访问数据的逻辑,聚合类负责管理数据。
- 符合开放封闭原则。想要实现新的访问方式只需要新增迭代器即可。
缺点
- 增加了系统的复杂性。
- 需要熟悉数据结构。
这也不算啥缺点哈哈,应该是我们的缺点。
原则
“+”代表遵守,“-”代表不遵守或者不相关
原则 | 开放封闭 | 单一职责 | 迪米特 | 里氏替换 | 依赖倒置 | 接口隔离 | 合成复用 |
---|---|---|---|---|---|---|---|
+ | + | – | – | – | – | – | |
适用场景
- 需要自己定义数据结构并且希望不暴露聚合对象中的细节。
- 需要使用不同的方式访问数据。
如何实现
想要实现迭代器模式,需要以下四样东西:
- 聚合抽象类/接口:定义聚合类的基本方法,增加、删除数据,以及提供迭代器创建的方法。
- 聚合类:实现聚合抽象类/接口。
- 迭代器抽象类:定义具体迭代器类的方法,通常包含hasNext()、first()、next()。
- 迭代器类:实现迭代器抽象类。
类图
这是我复制的类图,这里的具体聚合类是由具体迭代器去访问的。
例子
我也举不出什么好例子,就写一个简单的数组集合和迭代器吧。
类图
代码
迭代器抽象类
/**
* 迭代器抽象类
*
* @author xuxiaobai
*/
public abstract class Iterator {
//数组结尾下标
int end;
//当前位子
int currentIndex = 0;
/**
* 是否有下一个
* @return true:存在下一个,false:没有下一个
*/
abstract boolean hasNext();
/**
* 倒回第一个数据
* @return
*/
abstract int first();
/**
* 下一个
* @return
*/
abstract int next();
}
复制代码
聚合类&迭代器类
package test.model.iterator;
/**
* 聚合类
*
* @author xuxiaobai
*/
public class SimpleArrayList implements SimpleList{
//数组
private int[] array;
//数组的数据存储到那个下标+1
private int index=0;
public SimpleArrayList(int size) {
array = new int[size];
}
@Override
public void add(int o) {
array[index++]= o;
}
@Override
public void remove(int index) throws IllegalAccessException {
//暂不实现
throw new IllegalAccessException();
}
@Override
public Iterator iterator() {
return new SimpleIterator();
}
/**
* 迭代器类
*/
private class SimpleIterator extends Iterator {
public SimpleIterator(){
super.end=array.length-1;
}
@Override
boolean hasNext() {
if (super.currentIndex>=super.end){
return false;
}
return true;
}
@Override
int first() {
super.currentIndex=0;
return array[currentIndex];
}
@Override
int next() {
if (super.currentIndex>=super.end){
//当下标超等于或超过结尾,抛出数组越界异常
throw new ArrayIndexOutOfBoundsException();
}
super.currentIndex++;
return array[super.currentIndex];
}
}
}
复制代码
测试类
/**
* Created on 2021/6/10.
*
* @author xuxiaobai
*/
public class IteratorTest {
public static void main(String[] args) {
SimpleList list=new SimpleArrayList(10);
for (int i = 0; i < 10; i++) {
list.add(i);
}
Iterator iterator = list.iterator();
System.out.println("---开始遍历---");
while (iterator.hasNext()){
System.out.println(iterator.next());
}
/**
* 结果:
* ---开始遍历---
* 1
* 2
* 3
* 4
* 5
* 6
* 7
* 8
* 9
*/
}
}
复制代码
这里简单的实现了一个迭代器,如果你想要实现更加复杂的功能,可以参考ArrayList来做实现,我这里就不过多做演示了。
总结
总结就是一句话,迭代器模式很常用,但我们很少去自己实现迭代器模式,简单地了解一下就好了。
迭代器模式,把遍历数据和管理数据分离,提高了遍历方式的扩展性,我们可以通过定义新的迭代器来实现不同的遍历方式。
——————————————————————————————
你知道的越多,不知道的就越多。
如果本文章内容有问题,请直接评论或者私信我。如果觉得我写得还不错的话,点个赞也是对我的支持哦
未经允许,不得转载!
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END