5迭代器模式
迭代器模式
迭代器模式(Iterator Pattern) 是最常被使用的几个模式之一,被广泛地应用到java的API中。例如,Java的集合(Collection)框架中,就广泛使用迭代器来遍历集合中的元素。
1迭代器模式的定义
迭代器模式的英文原文:
Provide a way to access the elements of an aggregate object sequentially without exposing its underlying representation.
意思是:
提供一种方法访问一个容器对象中的各个元素,而又不需要暴露该对象的内部细节。
迭代器是为容器服务的,容器是指用来容纳其他对象的对象。例如,Collection集合类型、Set类等。迭代器模式便于遍历和访问容器中的各个元素。
迭代器模式有以下4个角色:
- 抽象迭代器(Iterator)角色:该角色负责定义访问和遍历元素的接口。
- 具体迭代器(Concrete )角色:该角色实现Iterator接口,完成容器元素的遍历。
- 抽象聚集(Aggregate)角色:该角色提供创建迭代器角色的接口。
- 具体聚集(Concrete Aggregate)角色:该角色实现抽象聚集接口,创建出容纳迭代器的对象。
Iterator.java
package com.eric.行为型模式.迭代器模式.引例;
/**
* @author Eric
* @ProjectName my_design_23
* @description 抽象迭代器接口
* @CreateTime 2020-12-10 09:57:19
*/
public interface Iterator {
//下一个元素
public Object next();
//判断有无,下一个元素
public boolean HasNext();
}
抽象迭代器接口主要有两个抽象方法:获取下一个元素、判断是否存在下一个元素。
创建抽象迭代器接口的实现类
ConcreteIterator.java
package com.eric.行为型模式.迭代器模式.引例;
/**
* @author Eric
* @ProjectName my_design_23
* @description 具体迭代器
* @CreateTime 2020-12-10 09:58:46
*/
public class ConcreteIterator implements Iterator{
private ConcreteAggregate agg;
private int index = 0;
private int size = 0;
ConcreteIterator(ConcreteAggregate agg) {
this.agg = agg;
this.size = agg.size();
index = 0;
}
//返回下一个元素
@Override
public Object next() {
if(index < size){
return agg.getElement(index++);
}
return null;
}
//是否有下一个元素
@Override
public boolean HasNext() {
return index < size;
}
}
具体的迭代器实现类要实现抽象迭代器的接口,并实现两个抽象方法。
属性中加入聚集类,后面会依次创建。
创建抽象聚集接口
Aggregate.java
package com.eric.行为型模式.迭代器模式.引例;
/**
* @author Eric
* @ProjectName my_design_23
* @description 抽象聚集接口
* @CreateTime 2020-12-10 09:59:41
*/
public interface Aggregate {
//添加元素到容器
public void add(Object object);
//创建迭代器
public Iterator createIterator();
}
抽象聚集接口定义了两个方法,添加元素到容器和创建迭代器的抽象方法。
创建具体聚集类实现抽象聚集接口
ConcreteAggregate.java
package com.eric.行为型模式.迭代器模式.引例;
import javax.naming.InsufficientResourcesException;
import java.util.Vector;
/**
* @author Eric
* @ProjectName my_design_23
* @description 具体聚集接口
* @CreateTime 2020-12-10 10:01:43
*/
public class ConcreteAggregate implements Aggregate{
//vector容器
private Vector vector = new Vector();
@Override
public void add(Object object) {
this.vector.add(object);
}
public Object getElement(int index)
{
if(index < vector.size()){
return vector.get(index);
}else{
return null;
}
}
public int size()
{
return vector.size();
}
@Override
public Iterator createIterator() {
return new ConcreteIterator(this);
}
}
创建测试类,进行测试。
Client.java
package com.eric.行为型模式.迭代器模式.引例;
/**
* @author Eric
* @ProjectName my_design_23
* @description 测试类
* @CreateTime 2020-12-10 10:35:00
*/
public class Client {
public static void main(String[] args) {
//定义聚集对象
ConcreteAggregate agg = new ConcreteAggregate();
agg.add("Eric");
agg.add("error");
agg.add("hh");
//遍历
Iterator iterator = agg.createIterator();
while (iterator.HasNext()){
System.out.println(iterator.next());
}
}
}
测试结果
2迭代器模式的应用
a.迭代器模式的优缺点
迭代器模式的优点
- 迭代器模式简化了访问容器元素的操作,具备一个统一的遍历接口。
- 封装遍历算法,使算法独立于聚集角色。客户无需知道聚集对象的类型,即使对象的类型发生变化,也不会影响遍历过程。
迭代器模式的缺点
- 迭代器模式给使用者一个序列化的错觉,从而产生错误。
- 迭代器的元素都是Object类型,没有类型特征(JDK1.5后通过引入泛型可以解决此问题)。
b.迭代器模式的使用场景
迭代器现在已经被广泛使用,甚至已经成为一个最基础的工具。有些人建议将迭代器模式从23种模式中删除,其原因就是迭代器模式过于普通,已经融合到各个语言和工具中。在Java语言中,从JDK1.2版本开始,增加了Java.util.Iterator接口,并将Iterator应用到各个聚合类中(Collection)类中,如ArrayList、Vector、Stack、HashSet等集合类都实现了iterator()方法,返回一个迭代器Iterator,便于对集合中的元素进行遍历。也正因为Java将迭代器模式已经融合到基本的API中,使我们在项目中无须在独立的写迭代器,直接使用即可。
注意:Java开发中,尽量不要自己写迭代器模式,使用JavaAPI中提供的迭代器一般就能满足项目需求。
3迭代器模式的实例。
迭代器的基本原理,上面已经演示过,因此接下来直接使用javaApi中的集合元素演示迭代器。
package com.eric.行为型模式.迭代器模式.例1;
import java.util.*;
/**
* @author Eric
* @ProjectName my_design_23
* @description 迭代器模式的演示
* @CreateTime 2020-12-10 11:04:51
*/
public class IteratorDemo {
public static void main(String[] args) {
//定义一个向量集合
Vector vector = new Vector();
vector.add("向量1");
vector.add("向量2");
vector.add("向量3");
vector.add("向量4");
//定义一个序列
List list = new ArrayList();
list.add("序列1");
list.add("序列2");
list.add("序列3");
//定义栈
Stack stack = new Stack();
stack.push("A");
stack.push("B");
stack.push("C");
stack.push("D");
stack.push("E");
//遍历集合
System.out.println("遍历向量元素");
show(vector.iterator());
System.out.println("\n\n遍历序列元素");
show(list.iterator());
System.out.println("\n\n遍历栈元素");
show(stack.iterator());
}
private static void show(Iterator iterator){
while (iterator.hasNext())
System.out.print(iterator.next()+" ");
}
}
测试结果
只要你不停下来,慢一点也没关系。