网站首页 > 技术文章 正文
基本介绍
通过“迭代”二字我相信大家大概就可以猜出该设计模式的使用场景了。那么大家可能就会有疑问了,遍历还需要设计模式吗?是不是有点过分了?别慌听我慢慢道来。
假设我们的集合是用不同的方式实现的,比如:数组、List、自定义的集合等等……
此时我们想遍历这些集合的话就需要使用不同的方式,并且我们还需要知道集合的内部结构,才能对应的选择适合的遍历方式。这样做的话是不是就有一些繁琐了呢?
为此就衍生出了“迭代器模式”,该模式的设计思想是:提供一种遍历不同集合元素的统一接口,并且无需暴露该集合的内部结构。
“迭代器模式”是属于行为型设计模式的一种。
迭代器模式UML类图
UML类图讲解
Iterator:迭代器接口。一般使用java内置的接口,该接口提供了遍历时所需的相关方法。
ConcreteIterator:实现了迭代器接口的具体迭代器类。用于迭代集合。
Aggregate:聚合接口。提供了返回迭代器和操作集合的方法。类似于java中的Collection接口。
ConcreteAggregate:实现了聚合接口的具体聚合类。该类含有一个集合并实现了聚合接口定义的方法。
Client:客户端。
注:通过UML类图我们可以发现,迭代器模式将“数据”和“迭代”进行了解耦。在整个结构当中分为两层,其中以Aggregate接口为首的是数据层,以Interator接口为首的是迭代层。
案例讲解
案例:编写一个通用遍历方法,可适用于遍历数组、List等。
迭代器接口使用java.util包下的Iterator接口。
具体迭代器类
/**
* 数组迭代器
*/
public class ArrayIterator implements Iterator {
// 需要遍历的数组
private String[] array;
// 遍历的位置
private int position = 0;
public ArrayIterator(String[] array) {
this.array = array;
}
/**
* 是否存在下一个元素
*/
@Override
public boolean hasNext() {
return position < array.length && array[position] != null;
}
/**
* 获取下一个元素
*/
@Override
public Object next() {
return array[position++];
}
}
/**
* List迭代器
*/
public class ListIterator implements Iterator {
// 需要遍历的集合
private List<String> list;
// 遍历的位置
private int position = 0;
public ListIterator(List<String> list) {
this.list = list;
}
/**
* 是否存在下一个元素
*/
@Override
public boolean hasNext() {
return position < list.size() && list.get(position) != null;
}
/**
* 获取下一个元素
*/
@Override
public Object next() {
return list.get(position++);
}
}
聚合接口
/**
* 聚合接口
*/
public interface Aggregate {
// 获取一个迭代器
Iterator createIterator();
}
具体的聚合接口
/**
* 数组聚合接口
*/
public class ArrayAggregate implements Aggregate {
// 存放数据的数组
private String[] array;
// 记录当前数组对象的个数
private int num;
public ArrayAggregate() {
this.array = new String[3];
}
/**
* 添加元素
*/
public void add(String value) {
this.array[num++] = value;
}
/**
* 获取对应的迭代器
*/
@Override
public Iterator createIterator() {
return new ArrayIterator(this.array);
}
}
/**
* List聚合接口
*/
public class ListAggregate implements Aggregate {
// 存放数据的List
private List<String> list;
public ListAggregate() {
this.list = new ArrayList<>();
}
/**
* 添加元素
*/
public void add(String value) {
this.list.add(value);
}
/**
* 获取对应的迭代器
*/
@Override
public Iterator createIterator() {
return new ListIterator(this.list);
}
}
客户端测试类
public class Client {
public static void main(String[] args) {
ArrayAggregate arrayAggregate = new ArrayAggregate();
arrayAggregate.add("小菜鸟");
arrayAggregate.add("点赞");
arrayAggregate.add("关注");
Iterator iterator = arrayAggregate.createIterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
}
}
执行结果
总结
1、迭代器模式提供一个统一的遍历元素的方法,客户端无需考虑是什么容器存放的元素。
2、客户端遍历集合时只需要获取一个迭代器即可完成遍历,无需知道聚合类的内部结构。
3、通过迭代器模式我们将管理对象集合和遍历对象集合的责任进行了拆分。这样的好处在于聚合对象和迭代器之间互不影响。这样的设计理念是符合单一职责原则的。
4、迭代器模式也是存在相应的问题的,最直观的问题是每个聚合对象都要有一个迭代器,会产生很多个迭代器类,造成类过多。
今天的分享就到这里了,如果感觉“菜鸟”写的文章还不错,记得点赞加关注呦!你们的支持就是我坚持下去的动力。文章哪里写的有问题的也希望大家可以指出,我会虚心受教。
猜你喜欢
- 2024-12-18 Java开发中MongoDB数据库相关操作
- 2024-12-18 HashMap有几种遍历方法?推荐使用哪种?
- 2024-12-18 在RedisTemplate中使用scan代替keys指令
- 2024-12-18 MQ的发布订阅模式(fanout) mq几种消息模式
- 2024-12-18 Mybatis参数-ParameterMapping处理参数
- 2024-12-18 既然有MySQL了,为什么还要有MongoDB?
- 2024-12-18 Java遍历一个 List 有哪些方式?每种的实现原理以及哪种最高效?
- 2024-12-18 为什么很多人不愿意用hibernate了?
- 2024-12-18 Qt中 QMap 类、QHash 类、QVector 类详解
- 2024-12-18 半小时搞懂 IO 模型 io模型详解
- 02-21走进git时代, 你该怎么玩?_gits
- 02-21GitHub是什么?它可不仅仅是云中的Git版本控制器
- 02-21Git常用操作总结_git基本用法
- 02-21为什么互联网巨头使用Git而放弃SVN?(含核心命令与原理)
- 02-21Git 高级用法,喜欢就拿去用_git基本用法
- 02-21Git常用命令和Git团队使用规范指南
- 02-21总结几个常用的Git命令的使用方法
- 02-21Git工作原理和常用指令_git原理详解
- 最近发表
- 标签列表
-
- cmd/c (57)
- c++中::是什么意思 (57)
- sqlset (59)
- ps可以打开pdf格式吗 (58)
- phprequire_once (61)
- localstorage.removeitem (74)
- routermode (59)
- vector线程安全吗 (70)
- & (66)
- java (73)
- org.redisson (64)
- log.warn (60)
- cannotinstantiatethetype (62)
- js数组插入 (83)
- resttemplateokhttp (59)
- gormwherein (64)
- linux删除一个文件夹 (65)
- mac安装java (72)
- reader.onload (61)
- outofmemoryerror是什么意思 (64)
- flask文件上传 (63)
- eacces (67)
- 查看mysql是否启动 (70)
- java是值传递还是引用传递 (58)
- 无效的列索引 (74)