行为篇-迭代器模式-创新互联
- 前言
- 一、物以类聚
- 二、遍历标准化
- 三、手写迭代器
- 1.定义迭代器
- 2.行车记录仪类
- 3.客户端类
- 总结
前言
迭代,在程序中特指对某集合中各元素逐个取用的行为。迭代器模式(Iterator)提供了一种机制来按顺序访问集合中的各元素,而不需要知道集合内部的构造。换句话讲,迭代器满足了对集合迭代的需求,并向外部提供了一种统一的迭代方式,而不必暴露集合的内部数据结构。
提示:以下是本篇文章正文内容,下面案例可供参考
二、遍历标准化迭代的过程是基于一系列数据展开的,所以集合是不得不提的概念。物以类聚,集合是由一个或多个确定的元素构成的整体,其实就是把一系列类似的元素按某种数据结构集结起来,作为一个整体来引用,以便于维护。简单来讲,可以把集合理解为“一堆”或者“一群”类似的元素集结起来的整体。为了承载不同的数据形式,集合类提供了多种多样的数据结构,如我们常用的ArrayList、HashSet、HashMap等,
每种集合都有不同的特性,可以满足对各种数据结构的承载需求。有了集合才会产生对其迭代的需求,而每种数据结构的迭代方式又不尽相同,所以,定义标准化的迭代器势在必行,以提供统一、通用的使用方法。
三、手写迭代器不同的数据结构需要不同的集合类,而针对不同的集合类的迭代方式也不尽相同,如for、foreach、while,甚至Java8引入的流式遍历等。举个例子,我们可以使用传统的for循环对List集合进行迭代遍历,而对于Set集合,for循环就无能为力了,这是因为Set本身集合不存在index索引号,所以必须用foreach循环(迭代器Iterator)进行遍历。难道就没有一种通用的迭代标准,能让调用者使用统一的方式进行遍历吗?如果我们深究源码就会发现,Collection接口中有这样一个接口。
Collection接口的一段源码,可以看到其明确声明了获取迭代器的接口iterator(),通过调用这个接口就可以返回标准的迭代器对象。既然有了这种标准,那么Collection这集合类就可以实现自己的迭代器。而Map集合也可以按照同样的方式,从其EntrySet中获取迭代器。可见,标准化的迭代器其实已经被各种集合类实现了,否则用户就无法站在Collection接口的抽象高度上对任何集合进行统一遍历。
1.定义迭代器汽车前挡风玻璃上安装了一台行车记录仪,它最主要的一项功能就是记录行驶路途中所拍摄的视频信息,以防发生交通事故后作为证据之用。我们知道,行车记录仪所记录下来的视频文件是比较大的,同时其存储空间又是有限的,那么它是怎样确保一直不间断地录制视频,并且存储空间不被占满呢?这就需要我们深究其内部数据结构了。
其实,行车记录仪的视频录制存盘操作有循环覆写的特性,待空间不够用时,新录的视频就会覆盖最早的视频,以首尾相接的环形结构来解决存储空间有限的问题。
public interface Iterator{//返回下一个元素
E next();
//是否还有下一个元素
boolean hasNext();
}
2.行车记录仪类public class DrivingRecorder{private int index = -1;//当前记录的位置
private String[] records = new String[10]; //假设只能记录10条视频
public void append(String record){//索引重置,从头覆盖
if(index == 9 ){index = 0;
}else {index++;
}
records[index] = record;
}
public Iteratoriterator() {return new Itr();
}
private class Itr implements Iterator{int cursor = index;//迭代器游标,不破及原始集合索引
int loopCount = 0;
@Override
public String next() {int i = cursor;
if(cursor == 0){cursor = 9;
}else {cursor--;
}
loopCount++;
return records[i];
}
@Override
public boolean hasNext() {return loopCount< 10;
}
}
}
3.客户端类public class Client {public static void main(String[] args) {DrivingRecorder dr = new DrivingRecorder();
for (int i = 0; i< 12; i++) {dr.append("视频_" + i);
}
ListuStorage = new ArrayList<>();
Iterator it = dr.iterator();
while (it.hasNext()){String video = (String) it.next();
System.out.println(video);
if("视频_10".equals(video) || "视频_8".equals(video)){uStorage.add(video);
}
}
System.out.println("事故证据" + uStorage);
}
}
输出结果:
视频_11
视频_10
视频_9
视频_8
视频_7
视频_6
视频_5
视频_4
视频_3
视频_2
事故证据[视频_10, 视频_8]
说明:
- 至此,我们实现的迭代器已经基本完成,用户不但可以使用Iterator进行迭代,而且foreach循环也得到了支持,用户再也不必为捉摸不定的迭代方式而犯愁了。当然,为保持简单,我们并没有实现迭代器的所有功能接口,例如对remove()功能接口的实现,利用这个接口用户便可以删除视频记录了。读者可以在此基础上继续代码实践,需要注意的是对迭代器游标的控制。
提示:这里对文章进行总结:
为了完成对各种集合类的遍历,我们定义了统一的迭代器接口Iterator,基于此我们让集合以内部类的方式实现其特有的迭代逻辑,再将自己标记为Iterable并返回迭代器实例,以证明自己是具备迭代能力的。具体的集合内部结构与迭代逻辑对于客户端这个“局外人”是透明的,客户端只需要知道这个集合是可以迭代的,并向集合发起迭代请求以获取迭代器即可以进行标准方式的遍历了。
迭代器模式的各角色定义如下:
- ConcreteAggregate(集合实现):实现集合接口Aggregate的具体集合类,可以实例化并返回一个迭代器以供外部使用。对应本章例程中的行车记录仪类DrivingRecorder。
- Iterator(迭代器接口):迭代器的接口标准,定义了进行迭代操作所需的一些方法,如next()、hasNext()等。
- ConcreteIterator(迭代器实现):迭代器接口Iterator的具体实现类,记录迭代状态并对外部提供所有迭代器功能的实现。
- Client(客户端):集合数据的使用者,需要从集合获取迭代器再进行遍历。
你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧
分享标题:行为篇-迭代器模式-创新互联
网址分享:http://azwzsj.com/article/dpcgig.html