「这是我参与2022首次更文挑战的第30天,活动详情查看:2022首次更文挑战」。
对于设计模式,我们都知道,是为了方便软件开发,让代码看起来更加规整,开发起来更有效率,从而总结的“经验”。
接下来的系列我们将会使用Java 语言,开始讲解一些常用的设计模式,带大家了解对应的设计规范。
迭代器模式
什么是迭代
可能有的人看到迭代两个字感觉比较难理解。迭代本身的含义是:更相替代;轮换。
对应到实际的Java 开发中,迭代的意思最常见的使用场景就是for循环。
Java 中的迭代器其实就是用一个游标,不断地指向下一个对象,每次处理一个对象,这样就不用把集合中的元素一下都塞到内存中处理。
迭代器模式
迭代器模式的目的就是让用户通过特定的接口访问容器(集合)的数据,不需要了解其内部的数据结构。
我们都知道,Java 里面有迭代接口Iterator,为什么我们还要再去设计一个迭代器呢?
因为Java 里面的迭代器不允许改变容器(集合)的内容。
举例:
public class Test {
public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
// 为list 添加元素
for (int i = 0; i < 5; i++) {
list.add(i);
}
// 获取迭代器
Iterator<Integer> it = list.iterator();
// 遍历元素
while(it.hasNext()) {
if(it.next().equals(3)) {
list.remove(it.next());
}
}
}
}
有兴趣的同学可以实际试一下,运行上述代码会报错。再一步证实了我们不能在迭代元素的时候进行增删改的操作。
同时还有另外一个重要的原因,就是我们在迭代元素的时候,是会有可能会去修改集合容器中的元素,而这种操作会带来极大的不安全。因为你不知道用户访问这个数据要执行什么操作。
于是,迭代器模式出现了,能为我们很好的解决上面的两个问题。
迭代器模式包含4 个角色:
(1)Aggregate集合:创建迭代子的接口;
(2)ConcreteAggregate 具体集合:实现迭代子接口;
(3)Iterator 迭代子接口:给出迭代每个元素的接口;
(4)ConcreteIterator 具体迭代子:实现迭代方法。
接下来我们用代码举例讲解一下:
第一步:定义抽象容器
public abstract class Aggregate {
// 定义迭代器
public abstract MyIterator iterator();
public abstract Object getElement(int index);
public abstract int size();
}
第二步:定义ConcreteAggregate 具体集合容器
public class ConcreteAggregate extends Aggregate{
private List<String> list=new ArrayList<>();
public ConcreteAggregate() {
list.add("元素1");
list.add("元素2");
list.add("元素3");
list.add("元素4");
}
@Override
public MyIterator iterator() {
return new ConcreteIterator(this);
}
public Object getElement(int index){
return list.get(index);
}
public int size(){
return list.size();
}
}
第三步:Iterator 迭代子接口
public interface MyIterator {
//移动到第一个对象
public void first();
//是否最后
public boolean isLast();
//移动下一个
public void next();
//当前对象
public Object current();
}
第四步:ConcreteIterator 具体迭代子
public class ConcreteIterator implements MyIterator{
Aggregate agg;
int size=0;
int index=0;
public ConcreteIterator(Aggregate agg) {
this.agg=agg;
size=agg.size();
}
@Override
public void first() {
index=0;
}
@Override
public boolean isLast() {
return index>=size;
}
@Override
public void next() {
if(index<size){
index++;
}
}
@Override
public Object current() {
return agg.getElement(index);
}
}
最后我们在客户端调用一下
public class Test {
public static void main(String[] args) {
Aggregate agg=new ConcreteAggregate();
MyIterator iterator = agg.iterator();
while(!iterator.isLast()){
System.out.println(iterator.current());
iterator.next();
}
}
}
其实,在我们日常开发中,迭代器模式是使用的比较少的一个设计模式。这里我们就理解一下它的思想就好了。文章开始说的java 自带的迭代器的缺点,其实换一下用法就可以避免了,这里我们就不在赘述了。希望读者可以自行查明。