定义:提供一种方法顺序访问一个聚合对象种各个元素,而又不暴露该对象的内部表示。
使用场景:需要访问一个聚集对象,不管这些对象是什么都需要遍历的时候,你就应该考虑用迭代器模式或者是需要用多种方式遍历时。
优点:分离了集合对象的遍历行为,抽象出一个迭代器类来负责,不暴露集合的内部结构而让外部代码透明的访问集合内部的数据。
迭代部分:抽象迭代器类定义迭代方法,不同具体迭代器类有不同实现方法
聚集部分:抽象聚集类定义创建迭代器方法,不同具体聚集类有不同的管理聚集对象的方法
抽象聚集类
/**
* @author 州牧
* @description 抽象聚集类
* @since 2022-03-25 18:17
*/
public abstract class Aggregate {
public abstract Iterator createIterator();
}
具体聚集类
import java.util.ArrayList;
import java.util.List;
/**
* @author 州牧
* @description 具体聚集类
* @since 2022-03-25 18:19
*/
public class ConcreteAggregate extends Aggregate{
private List<Object> list = new ArrayList<>();
@Override
public Iterator createIterator() {
return new ConcreteIterator(this);
}
public int size(){
return list.size();
}
public Object getItem(int index){
return list.get(index);
}
public void setItem(Object value){
list.add(value);
}
}
迭代器抽象类
/**
* @author 州牧
* @description 迭代器抽象类
* @since 2022-03-25 18:15
*/
public abstract class Iterator {
public abstract Object next();
public abstract boolean hasNext();
}
具体迭代器
/**
* @author 州牧
* @description 具体迭代器类实现方法
* @since 2022-03-25 18:25
*/
public class ConcreteIterator extends Iterator{
private ConcreteAggregate aggregate;
private int count = 0;
public ConcreteIterator(ConcreteAggregate aggregate) {
this.aggregate = aggregate;
}
@Override
public Object next() {
return aggregate.getItem(count++);
}
@Override
public boolean hasNext() {
return count < aggregate.size() ;
}
}
使用效果
/**
* @author 州牧
* @description
* @since 2022-03-25 18:29
*/
public class Client {
public static void main(String[] args) {
ConcreteAggregate aggregate = new ConcreteAggregate();
aggregate.setItem("html");
aggregate.setItem("css");
aggregate.setItem("javascript");
aggregate.setItem("java");
aggregate.setItem("sql");
aggregate.setItem("linux");
Iterator i = aggregate.createIterator();
while(i.hasNext()){
System.out.println("语言:"+i.next());
}
}
}
/*
语言:html
语言:css
语言:javascript
语言:java
语言:sql
语言:linux
*/
可能你会对多种遍历方式留有困惑,因此在增加一种具体的聚集对象实现
DemoIterator
/**
* @author 州牧
* @description
* @since 2022-03-25 18:43
*/
public class DemoIterator extends Iterator{
private DemoAggregate aggregate;
private int index =0;
public DemoIterator(DemoAggregate aggregate) {
this.aggregate = aggregate;
}
@Override
public Object next() {
return aggregate.getItem(index++);
}
@Override
public boolean hasNext() {
return index < aggregate.size;
}
}
DemoAggregate
/**
* @author 州牧
* @description
* @since 2022-03-25 18:36
*/
public class DemoAggregate extends Aggregate{
private Object[] objects = new Object[100];
int index = 0;
int size = 0;
@Override
public Iterator createIterator() {
return new DemoIterator(this);
}
public int size(){
return size;
}
public Object getItem(int x){
return objects[x];
}
public void setItem(Object value){
size++;
objects[index++]=value;
}
}
使用效果
/**
* @author 州牧
* @description
* @since 2022-03-25 18:29
*/
public class Client {
public static void main(String[] args) {
DemoAggregate aggregate = new DemoAggregate();
aggregate.setItem("html");
aggregate.setItem("css");
aggregate.setItem("javascript");
Iterator iterator = aggregate.createIterator();
while(iterator.hasNext()){
System.out.println("name:"+iterator.next());
}
}
}
个人理解:特定的具体聚集类对应具体的迭代器类。当然,也可以声明一个额外的迭代器(注意此时迭代器并非由具体聚集类而创建),遍历具体聚集类。
迭代器模式使用范围广泛,java早已经内置迭代器模式,下面是java内置api的使用。
public class Test {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("spring");
list.add("spring mvc");
list.add("mybatis");
list.add("springboot");
list.add("redis");
Iterator<String> iterator = list.iterator();
while(iterator.hasNext()){
System.out.println("技术:"+iterator.next());
}
}
}
/*
技术:spring
技术:spring mvc
技术:mybatis
技术:springboot
技术:redis
*/