迭代器模式
是什么?
迭代器模式提供一种方法访问一个聚合对象中的各个元素,而又不暴露其内部的表示。
结构组成及作用
下图是模板方法模式的UML类图:
作用
举个例子,我们平常用的集合的iterator()
返回的iterator就是“迭代器”。事实上,java.util.Collection.iterator()
就是应用了迭代器模式。
为什么要使用迭代器模式?或者说,jdk的集合类为什么要实现迭代器模式呢?
我记得我刚开始学集合的时候,对于为何使用Iterator是有点疑惑。现在的话,我觉得迭代器起码能有这几点好处:
- 重要的一点是,它提供了一种遍历聚合的方式,但并不会暴露内部实现。譬如,我们能通过
ArrayList的iterator()
获得Iterator对象(而不是内部实现的数组),但是我们不看源码是不会知道ArrayList是使用数组实现的。 - 我们能通过共同的接口方法
next()
等实现集合的遍历操作,而不是每个不同的集合都构建一套操作,对于调用集合的Client来说,遍历代码能够重用共用。
示例实现
迭代器模式的实现在jdk中随处可见,可参考implement了java.util.Collection
接口的集合类。
效果及应用场景
迭代器模式可用来:
- 访问一个聚合对象的内容而无需暴露它的内部表示。
- 支持对聚合对象的多种遍历。
- 为遍历不同的聚合结构提供一个统一的接口(即, 支持多态迭代)。
后记
这里补充相关的foreach的实现原理。
foreach即形如以下代码的形式:
List<String> list = new ArrayList<>();
list.add...
...
for(String s : list) {
...
}
众所周知,foreach能遍历集合类,先看下例子:
public class TestIteratorCompileMain {
public static void main(String[] args) {
String[] strings = {"a", "b", "c", "d", "e"};
System.out.println("=====print string array =====");
for (String s : strings) {
System.out.println(s);
}
System.out.println("=====print list =====");
List<String> list = new ArrayList<>(Arrays.asList(strings));
for (String s : list) {
System.out.println(s);
}
}
}
那么应该有人疑惑为什么foreach能循环遍历集合? 我将上面的java类例子的.class文件利用工具反编译得出如下代码(其实也可用javap -verbose来查看):
String[] list = strings;
int var3 = strings.length;
for(int s = 0; s < var3; ++s) {
String s1 = list[s];
System.out.println(s1);
}
System.out.println("=====print list =====");
ArrayList var6 = new ArrayList(Arrays.asList(strings));
Iterator var7 = var6.iterator();
while(var7.hasNext()) {
String var8 = (String)var7.next();
System.out.println(var8);
}
}
}
对比上述两代码块,可得出结论:foreach是一个java语法糖。
那么foreach的适用范围是什么?
这是《java语言规范》对foreach的定义(Java Language Specification | 14.14.2. The enhanced for statement ),里面有一句话:
The type of the Expression must be Iterable or an array type (§10.1), or a compile-time error occurs.
也就是说foreach仅适用于实现了Iterator接口的类或数组类型。
references
[1]Erich Gamma,Richard Helm,Ralph Johnson,John Vlissides.设计模式:可复用面向对象软件的基础[M].中国:机械工业出版社,2000
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论