设计模式之迭代器模式(下)

3)使用内部类实现迭代器
1.JDK中的迭代器示例

为了能够让迭代器可以访问到聚合对象中的数据,还可以将迭代器类设计为聚合类的内部类

package java.util;

public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> {
    private class Itr implements Iterator<E> {
	    int cursor = 0;
        ......
    }
}
2.改写ProductList类

将ProductIterator类作为ProductList类的内部类。

//商品数据类:具体聚合类
public class ProductList extends AbstractObjectList {
	public ProductList(List products) {
		super(products);
	}
	
	public AbstractIterator createIterator() {
		return new ProductIterator();
	}
	
	//商品迭代器:具体迭代器,内部类实现
	private class ProductIterator implements AbstractIterator {
		private int cursor1;
		private int cursor2;
		
		public ProductIterator() {
			cursor1 = 0;
			cursor2 = objects.size() -1;
		}
		
		public void next() {
			if(cursor1 < objects.size()) {
				cursor1++;
			}
		}
		
		public boolean isLast() {
			return (cursor1 == objects.size());
		}
		
		public void previous() {
			if(cursor2 > -1) {
				cursor2--;
			}
		}
		
		public boolean isFirst() {
			return (cursor2 == -1);
		}
		
		public Object getNextItem() {
			return objects.get(cursor1);
		} 
			
		public Object getPreviousItem() {
			return objects.get(cursor2);
		} 	
	}
}
4)使用JDK内置迭代器
1.概述

在 Java 集合框架中,List和Set等聚合类都继承(或实现)了java.util.Collection接口,在Collection接口中声明了如下方法(部分)。

具体的 Java 聚合类可以通过实现该 iterator() 方法返回一个具体的 Iterator 对象。

package java.util;
 
public interface Collection<E> extends Iterable<E> {
  ……
  boolean add(Object c);
  boolean addAll(Collection c);
  boolean remove(Object o);
  boolean removeAll(Collection c);
  boolean remainAll(Collection c); 
  Iterator iterator();
  ……
}

JDK中定义了抽象迭代器接口Iterator,代码如下所示:

package java.util;
 
public interface Iterator<E> {
  boolean hasNext();
  E next();
  void remove();
}

hasNext()用于判断聚合对象中是否还存在下一个元素,为了不抛出异常,在每次调用next()之前需先调用hasNext(),如果有可供访问的元素,则返回true;

next()方法用于将游标移至下一个元素,通过它可以逐个访问聚合中的元素,它返回游标所越过的那个元素的引用;

remove()方法用于删除上次调用next()时所返回的元素。

2.原理

在第一个next()方法被调用时,迭代器游标由“元素1”与“元素2”之间移至“元素2”与“元素3”之间,跨越了“元素2”,因此next()方法将返回对“元素2”的引用;

在第二个next()方法被调用时,迭代器由“元素2”与“元素3”之间移至“元素3”和“元素4”之间,next()方法将返回对“元素3”的引用,如果此时调用remove()方法,即可将“元素3”删除。

在这里插入图片描述

如下代码可用于删除聚合对象中的第一个元素:

//collection是已实例化的聚合对象
Iterator iterator = collection.iterator();   
// 跳过第一个元素
iterator.next();	 
// 删除第一个元素
iterator.remove(); 	

注意:如果调用remove()之前,没有先对next()进行调用,将会抛出IllegalStateException异常,因为没有任何可供删除的元素。

3.类结构图

在JDK中,Collection接口和Iterator接口充当了迭代器模式的抽象层,分别对应于抽象聚合类和抽象迭代器,而Collection接口的子类充当了具体聚合类,下面列出了JDK中与List有关的类及它们之间的关系。

在这里插入图片描述

4.Iterator 和 ListIterator

在Iterator接口中定义的方法太少,只有三个,通过这三个方法只能实现正向遍历。

在ListIterator接口中声明了用于逆向遍历的hasPrevious()和previous()等方法进行了拓展。

5.使用JDK的迭代器代码示例
import java.util.*;
 
public class IteratorDemo {
  public static void process(Collection c) {
        //创建迭代器对象
   	  	Iterator i = c.iterator(); 
		
        //通过迭代器遍历聚合对象
		    while(i.hasNext()) {
			    System.out.println(i.next().toString());
		    }
   }
 
	public static void main(String args[]) {
	  Collection persons;
	  //创建一个ArrayList类型的聚合对象
    persons = new ArrayList(); 
		persons.add("张无忌");
		persons.add("小龙女");
		persons.add("令狐冲");
		persons.add("韦小宝");
		persons.add("袁紫衣");
		persons.add("小龙女");
		
		process(persons);
	}
}
5)总结
1.优点
  • 支持以不同的方式遍历一个聚合对象,在同一个聚合对象上可以定义多种遍历方式。

  • 迭代器简化了聚合类,在原有的聚合对象中不需要再自行提供数据遍历等方法。

  • 在迭代器模式中,由于引入了抽象层,增加新的聚合类和迭代器类都无须修改原有代码。

2.缺点
  • 迭代器模式将存储数据和遍历数据的职责分离,增加新的聚合类需要对应增加新的迭代器类,类的个数将成对增加,增加了系统的复杂性。

  • 抽象迭代器的设计难度较大,需要充分考虑到系统将来的扩展,例如JDK内置迭代器Iterator就无法实现逆向遍历,如果需要实现逆向遍历,只能通过其子类ListIterator等来实现,而ListIterator迭代器无法用于操作Set类型的聚合对象。

3.适用场景
  • 访问一个聚合对象的内容而无须暴露它的内部表示。

  • 需要为一个聚合对象提供多种遍历方式。

  • 遍历不同的聚合结构提供一个统一的接口,在该接口的实现类中为不同的聚合结构提供不同的遍历方式,在客户端可以一致性地操作该接口。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/530574.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

SWM341系列应用(ADC应用)

SWM341系列 ADC应用 1、测试不同外接输入阻抗的情况 芯片供电3.3v&#xff0c;通过电阻箱进行分压获取被测电压&#xff0c;应用SimpleADC0 例程库。实测外接100K上拉电阻&#xff0c;或外接10K电阻上拉电阻&#xff0c;调整电阻箱获取被测电压3.0v、1.65v、100mV、50mV&#x…

如何解决Python包管理问题:ERROR: Could not find a version that satisfies the requirement

如何解决Python包管理问题&#xff1a;“ERROR: Could not find a version that satisfies the requirement” 文章目录 如何解决Python包管理问题&#xff1a;“ERROR: Could not find a version that satisfies the requirement”错误描述问题分析解决方案检查包名确保网络连…

前端三剑客 —— JavaScript (第二节)

目录 内容回顾 数据类型 基本数据类型&#xff1a; 引用数据类型&#xff1a; 常见运算 算术运算符 比较运算符 逻辑运算符 赋值运算符 自增/减运算符 三目运算符 位运算符 内容回顾 1.概述 2.基本数据 1.使用方式&#xff08;行内、页面、外部&#xff09; 2.对话框…

Facebook直播延迟过高是为什么?

在进行Facebook直播 时&#xff0c;高延迟可能会成为一个显著的问题&#xff0c;影响观众的观看体验和互动效果。以下是一些导致Facebook直播延迟过高的可能原因&#xff1a; 1、网络连接问题 网络连接不稳定或带宽不足可能是导致Facebook直播延迟的主要原因之一。如果您的网络…

华为机试题

目录 第一章、HJ1计算字符串最后一个单词的长度&#xff0c;单词以空格隔开。1.1&#xff09;描述1.2&#xff09;解题第二章、算法题HJ2 计算某字符出现次数1.1&#xff09;题目描述1.2&#xff09;解题思路与答案第三章、算法题HJ3 明明的随机数1.1&#xff09;题目描述1.2&a…

机器学习工程师 |面试作业题记录|本科水平 | 附个人解答

如是我闻&#xff1a; 面试的是一家在加拿大的初创公司&#xff0c;我想他们是需要清纯质朴的廉价劳动力干点杂活&#xff0c;非常符合我目前的情况。祝我成功吧。以下是他们的面试作业题&#xff08;take home questions&#xff09;&#xff0c;主要考察了一些基础知识&#…

Linux虚拟内存简介

Linux&#xff0c;像多数现代内核一样&#xff0c;采用了虚拟内存管理技术。该技术利用了大多数程序的一个典型特征&#xff0c;即访问局部性&#xff08;locality of reference&#xff09;&#xff0c;以求高效使用CPU和RAM&#xff08;物理内存&#xff09;资源。大多数程序…

查看 Linux 接入的 USB 设备速率是 USB2 还是 USB3

查看接入 usb 设备的速率 使用以下命令查看接入的 USB 设备速率&#xff08;每一行最后的 xxM 字样&#xff09;。插入设备前查看一次&#xff0c;插入设备后查看一次&#xff0c;对比即可定位到刚插入的设备是哪一条。 lsusb -t命令输出如下图 对照 USB 速率表 对照 USB 速…

【TensorRT】TensorRT C# API 项目更新 (1):支持动态Bath输入模型推理(下篇)

4. 接口应用 关于该项目的调用方式在上一篇文章中已经进行了详细介绍&#xff0c;具体使用可以参考《最新发布&#xff01;TensorRT C# API &#xff1a;基于C#与TensorRT部署深度学习模型》&#xff0c;下面结合Yolov8-cls模型详细介绍一下更新的接口使用方法。 4.1 创建并配…

构建智能生态:详解同城O2O外卖跑腿APP的开发技术

同城O2O外卖跑腿APP作为这一新型服务的代表&#xff0c;其开发技术成为了当下技术界的热点之一。小编将深入讲解同城O2O外卖跑腿APP的开发技术&#xff0c;以期为开发者提供一些有益的参考和指导。 需求分析与功能设计 在开发同城O2O外卖跑腿APP之前&#xff0c;首先需要进行充…

openlayer实现webgis端绘制制图及编辑

在WebGIS端制图是指通过Web浏览器界面实现地理信息数据的可视化、编辑、分析以及地图产品的制作。这一过程通常涉及以下几个关键环节&#xff1a; **1. 前端技术栈&#xff1a; •HTML/CSS/JavaScript&#xff1a;作为Web开发的基础&#xff0c;用于构建用户界面布局、样式设…

Go —— channel (二)

一个空的 channel 会产生哪些问题 读写nil管道均会阻塞触发死锁。关闭的管道仍然可以读取数据&#xff0c;向关闭的管道写数据会触发panic。 问&#xff1a;如果有多个协程同时读取一个channel&#xff0c;channel会如何选择消费者 channel 会按照维护的 recvq 等待读消息的…

vue canvas绘制信令图,动态显示标题、宽度、高度

需求: 1、 根据后端返回的数据&#xff0c;动态绘制出信令图 2、根据 dataStatus 返回值&#xff1a; 0 和 1&#xff0c; 判断 文字内容的颜色&#xff0c;0&#xff1a;#000&#xff0c;1&#xff1a;red 3.、根据 lineType 返回值&#xff1a; 0 和 1&#xff0c; 判断 箭…

栈的详解和例题(力扣有效括号)

感谢各位大佬的光临&#xff0c;希望和大家一起进步&#xff0c;望得到你的三连&#xff0c;互三支持&#xff0c;一起进步 个人主页&#xff1a;LaNzikinh-CSDN博客 收入专栏:初阶数据结构_LaNzikinh篮子的博客-CSDN博客 文章目录 前言一.什么是栈二.栈的实现三.例题&#xff…

推荐系统(唐宇迪)含具体代码

一、推荐系统介绍 用户冷启动 1.1 经典流程 1.2 涉及的技术点 二、协同过滤与矩阵分解 2.1 基于物品流行度&#xff08;排行榜榜单&#xff09;的推荐算法 class popularity_recommender_py():def __init__(self):self.train_data Noneself.user_id Noneself.item_id None…

Java每日一题(三道同一类型的题)

前言 本文一共有三道题:1.两数之和 2.三数之和 3. 四数之和 为什么把这三道题放一起呢&#xff0c;因为三数之和是可以根据两数之和进行推导&#xff0c;四数之和可以根据三数之和进行推导。 两数之和 思路分析: 我的思路: 1.排序 2.使用左右指针 3.处理细节问题 先让数组…

人工智能——深度学习

4. 深度学习 4.1. 概念 深度学习是一种机器学习的分支&#xff0c;旨在通过构建和训练多层神经网络模型来实现数据的高级特征表达和复杂模式识别。与传统机器学习算法相比&#xff0c;深度学习具有以下特点&#xff1a; 多层表示学习&#xff1a;深度学习使用深层神经网络&a…

Java后端常见场景业务问题

目录 单点登录如何实现权限认证如何实现上传数据的安全性如何保证订单表每天新增500W数据,分库分表的方案应该如何设计?订单表每天新增500W数据,分库分表的方案应该如何设计?*********************项目日志如何采集已经上线的bug如何排查如何快速定位系统瓶颈单点登录如何实…

Golang使用PGO优化程序性能

文章目录 参考文章PGO是什么使用PGO的好处PGO做了什么热函数内联什么是内联内联的好处Go默认的内联策略PGO的热函数内联 去虚拟化调用指令高速缓存 PGO有什么缺点可执行程序变大构建时间变长 PGO怎么使用典型的工作流程收集CPU配置文件生产环境启动PGO代码改动重新生成CPU配置文…

基于Whisper语音识别的实时视频字幕生成 (一): 流式显示视频帧和音频帧

Whishow Whistream&#xff08;微流&#xff09;是基于Whisper语音识别的的在线字幕生成工具&#xff0c;支持rtsp/rtmp/mp4等视频流在线语音识别 1. whishow介绍 whishow&#xff08;微秀&#xff09;是在线音视频流播放python实现&#xff0c;支持rtsp/rtmp/mp4等输入&…