【java设计模式】(6)---迭代器模式(案例解析)
设计模式之迭代器模式
一、java迭代器介绍
1、迭代器接口
在jdk中,与迭代器相关的接口有两个:Iterator 与 Iterable。
Iterator:迭代器,Iterator及其子类通常是迭代器本身的结构与方法;迭代器是一种模式,它可以使得对于序列类型的数据结构的遍历行为与被遍历的对象分离,即我们无需关心该序列的底层结构是什么样子的。只要拿到
这个对象,使用迭代器就可以遍历这个对象的内部。
Iterable:可迭代的,那些想用到迭代器功能的其它类,如AbstractList HashMap等,需要实现该接口。
1)Iterator
Java提供一个专门的迭代器<<interface>>Iterator,我们可以对某个序列实现该interface,来提供标准的Java迭代器。Iterator接口实现后的功能是“使用”一个迭代器。
Package java.util;
public interface Iterator<E> {
//判断是否存在下一个对象元素
boolean hasNext();
//获得下一个元素
E next();
//移除下一个元素
void remove();
}
2)Iterable
Java中还提供了一个Iterable接口,Iterable接口实现后的功能是“返回”一个迭代器(Iterator),我们常用的实现了该接口的子接口有: Collection<E>, Deque<E>, List<E>, Queue<E>, Set<E> 等.该接口的iterator()方
法返回一个标准的Iterator实现。
public interface Iterable<T> {
Iterator<T> iterator();
}
2、迭代器的实现
看完源码,我们来看看迭代器是如何使用的:
1) 若类A想要使用迭代器,则它的类声明部分为 class A implement Iterable
2) 在类A实现中,要实现Iterable接口中的唯一方法:Iterator<T> iterator(); 这个方法用于返回一个迭代器,即Iterator接口及其子类;
3) 在类A中,定义一个内部类S,专门用于实现Iterator接口,定制类A自已的迭代器实现。
如下:
//A实现Iterable接口
class A implement Iterable
{
//该接口返回一个Iterator对象
Iterator<T> iterator() {...}
class S implement Iterator<E>
{
//上面这个对象会有具体实现的方法
boolean hasNext() {....}
E next() {....}
void remove() {....}
}
}
下面我们来看下抽象类AbstractList的jdk源码
public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> { // List接口实现了Collection<E>, Iterable<E> protected AbstractList() {
} ...
// 这里返回一个迭代器对象
public Iterator<E> iterator() {
return new Itr();
} // Itr内部类实现迭代器
private class Itr implements Iterator<E> { int cursor = 0;
int lastRet = -1;
int expectedModCount = modCount; // 实现hasNext方法
public boolean hasNext() {
return cursor != size();
}
// 实现next方法
public E next() {
//判断是否有下一个
checkForComodification();
try {
E next = get(cursor);
lastRet = cursor++;
//返回下一个
return next;
} catch (IndexOutOfBoundsException e) {
checkForComodification();
throw new NoSuchElementException();
}
}
// 实现remove方法
public void remove() {
if (lastRet == -1)
throw new IllegalStateException();
checkForComodification(); try {
AbstractList.this.remove(lastRet);
if (lastRet < cursor)
cursor--;
lastRet = -1;
expectedModCount = modCount;
} catch (IndexOutOfBoundsException e) {
throw new ConcurrentModificationException();
}
}
//判断是否有下一个方法
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
}
}
3、小案例
//实现Iterable
class ScanAppleStore implements Iterable<String> { ArrayList<String> appleStore = new ArrayList<String>();
//为初始appleStore赋值
ScanAppleStore() {
Collections.addAll(appleStore, "Sweet", "Sour", "Bitter", "litter Sweet", "litter Sour", "litter Bitter");
System.out.print(appleStore);
}
//重写Iterator方法
@Override
public Iterator<String> iterator() {
return new Iterator<String>() {
private int i = 0; public boolean hasNext() {
if (i < appleStore.size()) {
return true;
} else {
return false;
}
} public String next() { return appleStore.get(i++);
} public void remove() {
System.out.print("not defined!");
}
};
} public Iterable<String> reverseIterator() {
return new Iterable<String>() {
public Iterator<String> iterator() {
return new Iterator<String>() {
private int i = appleStore.size() - 1; public boolean hasNext() {
if (i > -1) {
return true;
} else {
return false;
}
} public String next() { return appleStore.get(i--);
} public void remove() {
System.out.print("not defined!");
}
};
}
}; }}
测试类
public class TestIterable {
//构造函数初始化
TestIterable() {
ScanAppleStore appleTree = new ScanAppleStore();
//采用系统自带的迭代器
System.out.println("采用系统自带的迭代器iterator:");
for (String str : appleTree) {
System.out.println(str); }
System.out.println("======================");
System.out.println("采用自己重新迭代器,让相反输出");
//采用自己重新迭代器,让相反输出
for (String str : appleTree.reverseIterator()) {
System.out.println(str);
}
} public static void main(String[] args) {
TestIterable a = new TestIterable(); }
}
运行结果:
[Sweet, Sour, Bitter, litter Sweet, litter Sour, litter Bitter]
采用系统自带迭代器iterator:
Sweet
Sour
Bitter
litter Sweet
litter Sour
litter Bitter
======================
采用自己重新迭代器,让相反输出:
litter Bitter
litter Sour
litter Sweet
Bitter
Sour
Sweet
二、迭代器模式
1、什么是迭代器模式
GOF给出的定义为:提供一种方法访问一个容器(container)对象中各个元素,而又不需暴露该对象的内部细节。
Iterator模式就是分离了集合对象的遍历行为,抽象出一个迭代器类来负责,这样既可以做到不暴露集合的内部结构,又可让外部代码透明的访问集合内部的数据。
2、迭代器模式角色组成
1) 迭代器角色(Iterator):迭代器角色负责定义访问和遍历元素的接口。
2) 具体迭代器角色(Concrete Iterator):具体迭代器角色要实现迭代器接口,并要记录遍历中的当前位置。
3) 容器角色(Container):容器角色负责提供创建具体迭代器角色的接口。
4) 具体容器角色(Concrete Container):具体容器角色实现创建具体迭代器角色的接口——这个具体迭代器角色于该容器的结构相关。
3、案例解析
1)迭代器角色
public interface Iterator {
public Object next();
public boolean hasNext();
}
2)具体迭代器角色
public class ConcreteIterator implements Iterator { private List list = new ArrayList();
private int cursor = 0; public ConcreteIterator(List list) {
this.list = list;
} @Override
public Object next() {
Object obj = null;
if (this.hasNext()) {
obj = this.list.get(cursor++);
}
return obj;
} @Override
public boolean hasNext() {
if (cursor == list.size()) {
return false;
}
return true;
}
}
3)容器角色
public interface Aggregate {
public void add(Object obj);
public void remove(Object obj);
public Iterator iterator();
}
4) 具体容器角色
public class ConcreteAggregate implements Aggregate { private List list = new ArrayList(); @Override
public void add(Object obj) {
list.add(obj);
}
@Override
public void remove(Object obj) {
list.remove(obj);
}
@Override
public Iterator iterator() {
return new ConcreteIterator(list);
}
}
测试类
public class Client { public static void main(String[] args) {
Aggregate ag = new ConcreteAggregate();
ag.add("小明");
ag.add("小红");
ag.add("小刚");
Iterator it = ag.iterator();
while (it.hasNext()) {
String str = (String) it.next();
System.out.println(str);
}
}}
运行结果
小明
小红
小刚
4、迭代器优点和缺点
优点:
1)它支持以不同的方式遍历一个聚合对象。
2)迭代器简化了聚合类。
3)在同一个聚合上可以有多个遍历。
4)在迭代器模式中,增加新的聚合类和迭代器类都很方便,无须修改原有代码。
缺点:
由于迭代器模式将存储数据和遍历数据的职责分离,增加新的聚合类需要对应增加新的迭代器类,类的个数成对增加,这在一定程度上增加了系统的复杂性。
参考
其实这整篇文章几乎都来自该篇文章,用参考都不太好意思,哈哈。
想太多,做太少,中间的落差就是烦恼。想没有烦恼,要么别想,要么多做。中校【7】
【java设计模式】(6)---迭代器模式(案例解析)的更多相关文章
- 16.java设计模式之迭代器模式
基本需求: 展示一个学校的结构,比如一个学校下面有多个学院,学院下面有多个系,对其节点主要是遍历,与组合模式略有不同 传统方案: 学校<-学院<-系 依次继承 这种方式,在一个页面中展示出 ...
- 折腾Java设计模式之迭代器模式
迭代器模式 Provide a way to access the elements of an aggregate object sequentially without exposing its ...
- 简单的了解下Java设计模式:迭代器模式(转载)
迭代器模式定义 迭代器模式(Iterator),提供一种方法顺序访问一个聚合对象中的各种元素,而又不暴露该对象的内部表示. Java 开发过程中遍历是常用的.如下边程序: for(int i =0 ; ...
- java设计模式之迭代器模式
一.迭代器模式简介 迭代器模式提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部的表示. 迭代器模式让我们能游走于聚合内的每一个元素,而又不暴露内部的表示.把游走的任务放在迭代器上,而不是 ...
- Python进阶:设计模式之迭代器模式
在软件开发领域中,人们经常会用到这一个概念——“设计模式”(design pattern),它是一种针对软件设计的共性问题而提出的解决方案.在一本圣经级的书籍<设计模式:可复用面向对象软件的基础 ...
- 设计模式学习--迭代器模式(Iterator Pattern)和组合模式(Composite Pattern)
设计模式学习--迭代器模式(Iterator Pattern) 概述 ——————————————————————————————————————————————————— 迭代器模式提供一种方法顺序 ...
- 实践GoF的设计模式:迭代器模式
摘要:迭代器模式主要用在访问对象集合的场景,能够向客户端隐藏集合的实现细节. 本文分享自华为云社区<[Go实现]实践GoF的23种设计模式:迭代器模式>,作者:元闰子. 简介 有时会遇到这 ...
- 【设计模式】Java设计模式 - 享元模式
Java设计模式 - 享元模式 不断学习才是王道 继续踏上学习之路,学之分享笔记 总有一天我也能像各位大佬一样 原创作品,更多关注我CSDN: 一个有梦有戏的人 准备将博客园.CSDN一起记录分享自己 ...
- Java设计模式——装饰者模式
JAVA 设计模式 装饰者模式 用途 装饰者模式 (Decorator) 动态地给一个对象添加一些额外的职责.就增加功能来说,Decorator 模式相比生成子类更为灵活. 装饰者模式是一种结构式模式 ...
- 浅析JAVA设计模式之工厂模式(一)
1 工厂模式简单介绍 工厂模式的定义:简单地说,用来实例化对象,取代new操作. 工厂模式专门负责将大量有共同接口的类实例化.工作模式能够动态决定将哪一个类实例化.不用先知道每次要实例化哪一个类. 工 ...
随机推荐
- go片段代码
关于枚举类型
- 通过zuul修改请求参数——对请求参数进行解密
zuul是netflix开源的一个API Gateway 服务器, 本质上是一个web servlet应用,Zuul 在云平台上提供动态路由,监控,弹性,安全等边缘服务的框架,Zuul 相当于是设备和 ...
- margin-top的兼容问题
产生的条件:子元素给了margin-top,并且父元素没有浮也没有其他样式,浏览器解析的结果是父元素下去了. 解决方法:1.给子元素或者父元素添加浮动,缺点:如果不需要浮动,添加浮动也页面布局会乱 2 ...
- Centos7中kubernetes-1.11.2基于配置亲和与反亲和
1.题目 通过命令行,创建两个个deployment. – 需要集群中有2个节点 – 第1个deployment名称为<hwcka-002-app1>,使用nginx镜像,用有2个pod, ...
- AI零基础入门之人工智能开启新时代—上篇
人工智能的发展史及应用 开篇:人工智能无处不在 人工智能的发展历程 · 1945艾伦图灵在论文<计算机器不智能>中提出了著名的图灵测试,给人工智能的収展产生了深远的影响. · 1951年, ...
- 【QT】QApplication简介
1.QApplication QApplication类管理GUI程序的控制流和主要设置,是基于QWidget的,为此特化了QGuiApplication的一些功能,处理QWidget特有的初始化和结 ...
- MongoDB 学习使用
博客教程: https://jingyan.baidu.com/article/dca1fa6f0428a4f1a440522e.html
- vue开发(开发环境+项目搭建)
Vue.js是一套构建用户界面的渐进式框架.与其他重量级框架不同的是,Vue 采用自底向上增量开发的设计.Vue 的核心库只关注视图层,并且非常容易学习,非常容易与其它库或已有项目整合.另一方面,Vu ...
- c# 集合的长度为什么是可变的
摘要: 写在前面:此随笔仅仅是作为个人学习总结,有不对的地方,请各位前辈指正O(∩_∩)O........ 一: 引入 在学习集合之前我们都学习过数组.可以知道数组的长度在声明的时候就已经被固定了,不 ...
- cf 1142 C
忽然觉得这个题很有必要写题解. 移项 y-x^2 = bx+c 那么其实就是找有多少条直线上方没有点 所以就是一个上凸壳有多少条直线/点. 绝妙啊!!!! 太妙了啊!!!! 神乎其技卧槽!!! (我是 ...