迭代器模式(Iterator Pattern)
Posted 顧棟
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了迭代器模式(Iterator Pattern)相关的知识,希望对你有一定的参考价值。
迭代器模式(Iterator Pattern)
迭代器模式的定义
它提供一种方法访问一个容器对象中各个元素,而又不需暴露该对象的内部细节。迭代器是为容器服务的,那什么是容器呢? 能容纳对象的所有类型都可以称之为容。例如Collection集合类型、Set类型等,迭代器模式就是为解决遍历这些容器中的元素而诞生的。
迭代器模式的优点
- 访问一个聚合对象的内容而无须暴露它的内部表示。
- 遍历任务交由迭代器完成,这简化了聚合类。
- 它支持以不同方式遍历一个聚合,甚至可以自定义迭代器的子类以支持新的遍历。
- 增加新的聚合类和迭代器类都很方便,无须修改原有代码。
- 封装性良好,为遍历不同的聚合结构提供一个统一的接口。
迭代器模式的缺点
- 增加了类的个数,这在一定程度上增加了系统的复杂性。
迭代器模式的结构
- 抽象聚合(Aggregate)角色:抽象容器,定义存储、添加、删除聚合对象以及创建迭代器对象的接口,必然提供一个类似createIterator()这样的
方法,在Java中一般是iterator()方法。 - 具体聚合(ConcreteAggregate)角色:具体容器,实现抽象聚合类,返回一个具体迭代器的实例。
- 抽象迭代器(Iterator)角色:定义访问和遍历聚合元素的接口,通常包含 hasNext()、first()、next() 等方法。
- 具体迭代器(Concretelterator)角色:实现抽象迭代器接口中所定义的方法,完成对聚合对象的遍历,记录遍历的当前位置。
迭代器模式的实现
一般实现
/**
* 抽象迭代器
*/
public interface Iterator {
/**
* 遍历到下一个元素
*/
public Object next();
/**
* 是否已经遍历到尾部
*/
public boolean hasNext();
/**
* 删除当前指向的元素
*/
public boolean remove();
}
/**
* 具体迭代器
*/
public class ConcreteIterator implements Iterator {
private Vector vector = new Vector();
/**
* 定义当前游标
*/
public int cursor = 0;
@SuppressWarnings("unchecked")
public ConcreteIterator(Vector vector) {
this.vector = vector;
}
/**
* 遍历到下一个元素
*/
@Override
public Object next() {
Object result = null;
if (this.hasNext()) {
result = this.vector.get(this.cursor++);
}
return result;
}
/**
* 是否已经遍历到尾部
*/
@Override
public boolean hasNext() {
return this.cursor != this.vector.size();
}
/**
* 删除当前指向的元素
*/
@Override
public boolean remove() {
this.vector.remove(this.cursor);
return true;
}
}
/**
* 抽象容器
*/
public interface Aggregate {
/**
* 是容器必然有元素的增加
*/
public void add(Object object);
/**
* 减少元素
*/
public void remove(Object object);
/**
* 由迭代器来遍历所有的元素
*/
public Iterator iterator();
}
/**
* 具体容器
*/
public class ConcreteAggregate implements Aggregate {
/**
* 容纳对象的容器
*/
private Vector vector = new Vector();
/**
* 是容器必然有元素的增加
*
* @param object
*/
@Override
public void add(Object object) {
this.vector.add(object);
}
/**
* 减少元素
*
* @param object
*/
@Override
public void remove(Object object) {
this.vector.remove(object);
}
/**
* 由迭代器来遍历所有的元素
*/
@Override
public Iterator iterator() {
return new ConcreteIterator(this.vector);
}
}
public static void main(String[] args) {
//声明出容器
Aggregate agg = new ConcreteAggregate();
//产生对象数据放进去
agg.add("abc");
agg.add("aaa");
agg.add("1234");
//遍历一下
Iterator iterator = agg.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
agg.remove("aaa");
iterator = agg.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
}
参考JDK实现数遍历
/**
* 迭代器
*/
public interface Iterator<E> {
boolean hasNext();
E next();
}
/**
* 可迭代接口
*/
public interface Iterable<E> {
Iterator<E> iterator();
}
/**
* 集合功能接口定义
*/
public interface Collection<E, L> extends Iterable<E> {
boolean add(E e);
boolean remove(E e);
boolean addLink(String key, L l);
boolean removeLink(String key);
@Override
Iterator<E> iterator();
}
/**
* 雇员
*/
public class Employee {
/**
* ID
*/
private String uId;
/**
* 姓名
*/
private String name;
/**
* 备注
*/
private String desc;
public Employee(String uId, String name) {
this.uId = uId;
this.name = name;
}
public Employee(String uId, String name, String desc) {
this.uId = uId;
this.name = name;
this.desc = desc;
}
public String getuId() {
return uId;
}
public void setuId(String uId) {
this.uId = uId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
}
/**
* 树节点链路
*/
public class Link {
/**
* 雇员fromId
*/
private String fromId;
/**
* 雇员ID
*/
private String toId;
public Link(String fromId, String toId) {
this.fromId = fromId;
this.toId = toId;
}
public String getFromId() {
return fromId;
}
public void setFromId(String fromId) {
this.fromId = fromId;
}
public String getToId() {
return toId;
}
public void setToId(String toId) {
this.toId = toId;
}
}
/**
* (核⼼)迭代器功能实现
*/
public class GroupStructure implements Collection<Employee, Link> {
/**
* 组织ID,也是一个组织链的头部ID
*/
private final String groupId;
/**
* 组织名称
*/
private String groupName;
/**
* 雇员列表
*/
private final Map<String, Employee> employeeMap = new ConcurrentHashMap<>();
/**
* 组织架构关系;id->list
*/
private final Map<String, List<Link>> linkMap = new ConcurrentHashMap<>();
/**
* 反向关系链
*/
private final Map<String, String> invertedMap = new ConcurrentHashMap<>();
public GroupStructure(String groupId, String groupName) {
this.groupId = groupId;
this.groupName = groupName;
}
@Override
public boolean add(Employee employee) {
return null != employeeMap.put(employee.getuId(), employee);
}
@Override
public boolean remove(Employee o) {
return null != employeeMap.remove(o.getuId());
}
@Override
public boolean addLink(String key, Link link) {
invertedMap.put(link.getToId(), link.getFromId());
if (linkMap.containsKey(key)) {
return linkMap.get(key).add(link);
} else {
List<Link> links = new LinkedList<>();
links.add(link);
linkMap.put(key, links);
return true;
}
}
@Override
public boolean removeLink(String key) {
return null != linkMap.remove(key);
}
@Override
public Iterator<Employee> iterator() {
return new Iterator<Employee>() {
final HashMap<String, Integer> keyMap = new HashMap<>();
int totalIdx = 0;
private String fromId = groupId; // 雇员ID,From
private String toId = groupId; // 雇员ID,To
@Override
public boolean hasNext() {
return totalIdx < employeeMap.size();
}
@Override
public Employee next() {
List<Link> links = linkMap.get(toId);
int cursorIdx = getCursorIdx(toId);
// 同级节点扫描
if (null == links) {
cursorIdx = getCursorIdx(fromId);
links = linkMap.get(fromId);
}
// 上级节点扫描
while (cursorIdx > links.size() - 1) {
fromId = invertedMap.get(fromId);
cursorIdx = getCursorIdx(fromId);
links = linkMap.get(fromId);
}
// 获取节点
Link link = links.get(cursorIdx);
toId = link.getToId();
fromId = link.getFromId();
totalIdx++;
// 返回结果
return employeeMap.get(link.getToId());
}
public int getCursorIdx(String key) {
int idx = 0;
if (keyMap.containsKey(key)) {
idx = keyMap.get(key);
keyMap.put(key, ++idx);
} else {
keyMap.put(key, idx);
}
return idx;
}
};
}
}
public static void main(String[] args) {
GroupStructure groupStructure = new GroupStructure("1", "组织");
groupStructure.add(new Employee("2", "员工1", "二级部门"));
groupStructure.add(new Employee("3", "员工2", "二级部门"));
groupStructure.add(new Employee("4", "员工3", "三级部门"));
groupStructure.add(new Employee("5", "员工4", "三级部门"));
groupStructure.add(new Employee("6", "员工6", "四级部门"));
groupStructure.add(new Employee("7", "员工5", "四级部门"));
groupStructure.add(new Employee("8", "员工7", "四级部门"));
groupStructure.addLink("1", new Link("1", "2"));
groupStructure.addLink("1", new Link("1", "3"));
groupStructure.addLink("2", new Link("2", "4"));
groupStructure.addLink("2", new Link("2", "5"));
groupStructure.addLink("5", new Link("5", "6"));
groupStructure.addLink("5", new Link("5", "7"));
groupStructure.addLink("5", new Link("5", "8"));
Iterator<Employee> iterator = groupStructure.iterator();
while (iterator.hasNext()) {
Employee employee = iterator.next();
System.out.println(employee.getDesc() + ",雇员 Id:" + employee.getuId() + " Name:" + employee.getName());
}
}
适用场景
- 当需要为聚合对象提供多种遍历方式时。
- 当需要为遍历不同的聚合结构提供一个统一的接口时。
- 当访问一个聚合对象的内容而无须暴露其内部细节的表示时。
本文主要参考:
- 小傅哥的《重学Java模式》
- 《C语言中文网》设计模式的相关内容
- 《设计模式之禅》第二版 秦小波
以上是关于迭代器模式(Iterator Pattern)的主要内容,如果未能解决你的问题,请参考以下文章
设计模式 - 迭代器模式(iterator pattern) 具体解释