迭代器模式(Iterator Pattern),提供了顺序访问集合中每个元素的功能,并且不用暴露其对象内部表示。
简单来说,就是实现一个迭代功能,迭代功能,每种编程语言都有,比如for循环就可以直接用,但是for循环有个问题就是,使用for循环,要明确知道被遍历的对象是什么,只有知道了类型,才能操作获取其中的对象。
如果是数组,那么就是下面这种:
int[] arrs = new int[]{1,2,3,4,5};
for(int i=0;i<=arrs.length; i++) {
arrs[i]
...
}
如果是集合,那么遍历的方式,判断集合长度,就要变成:
for(int i=0;i<=list.size(); i++) {
list.get(i)
...
}
这就是我们上面阐述的问题,我需要明确知道被遍历对象是什么。
并且像上面,内部的一组对象类型也要统一。
而使用迭代器,这些差异,将会被迭代器封装,不管是数组、ArrayList、LinkedList等等,最后调用迭代获取元素的方式是统一的,从表面看是没有差异的,这就是迭代器模式的优势。
我们来看一下演示代码:
1、新建自定义抽象迭代器
package com.itzhimei.study.design.iterator;
/**
* www.itzhimei.com
* 迭代器模式--自定义抽象迭代器
*/
public interface IMyIterator {
boolean hasNext();
Object next();
}
2、新建自定义实现具体迭代器
package com.itzhimei.study.design.iterator;
import java.util.ArrayList;
/**
* www.itzhimei.com
* 迭代器模式--自定义实现具体迭代器
*/
public class MyIterator implements IMyIterator {
private ArrayList<Object> list;
private int index = -1;
public MyIterator(ArrayList<Object> list) {
this.list = list;
}
/**
* 判断是否还有元素
* @return
*/
@Override
public boolean hasNext() {
return this.list == null ? false: (index < list.size()-1);
}
/**
* 获取元素
* @return
*/
@Override
public Object next() {
if(this.list != null && index < list.size()-1) {
return this.list.get(++index);
}
return null;
}
}
3、新建自定义抽象迭代器持有类
package com.itzhimei.study.design.iterator;
/**
* www.itzhimei.com
* 迭代器模式--自定义抽象迭代器持有类
*/
public interface IMyList {
IMyIterator iterator();
}
4、新建自定义具体迭代器持有类
package com.itzhimei.study.design.iterator;
import java.util.ArrayList;
/**
* www.itzhimei.com
* 迭代器模式--自定义具体迭代器持有类
*/
public class MyList implements IMyList{
ArrayList<Object> list;
public MyList(ArrayList<Object> list) {
this.list = list;
}
@Override
public IMyIterator iterator() {
return new MyIterator(this.list);
}
}
5、新建用于迭代的Person类
package com.itzhimei.study.design.iterator;
/**
* www.itzhimei.com
* 迭代器模式--Person类用于测试
*/
public class Person {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
6、测试
package com.itzhimei.study.design.iterator;
import java.util.ArrayList;
/**
* www.itzhimei.com
* 测试
*/
public class Client {
public static void main(String[] args) {
Person p1 = new Person();
p1.setName("张三");
Person p2 = new Person();
p2.setName("李四");
Person p3 = new Person();
p3.setName("王五");
ArrayList ps = new ArrayList();
ps.add(p1);
ps.add(p2);
ps.add(p3);
IMyList list = new MyList(ps);
IMyIterator iterator = list.iterator();
while(iterator.hasNext()) {
Object next = iterator.next();
System.out.println("迭代打印Person Name:"+((Person)next).getName());
}
}
}
输出结果:
迭代打印Person Name:张三
迭代打印Person Name:李四
迭代打印Person Name:王五
类关系图:
总结:
迭代器的优势
1、迭代器不需要知道结合对象内部实现细节,就能够实现集合元素的遍历;
2、使用迭代器后,获取元素的方式,就不再是下标,而是通过通用方式,比如这里演示代码中的next()方法;你可能会说,你的next代码中也使用了下标获取元素才返回的,确实如此,这是因为视角不同,我们使用迭代器模式,好处在于将集合的迭代、元素获取,同某一个集合的具体迭代方式、使用方式解耦。
还是那句话,设计模式都是在特定的场景下,才能发挥巨大作用。