设计模式--迭代器模式

定义: 提供一种方法访问一个容器对象中的每个元素,而又不暴露该对象的内部细节。

迭代器模式的运用

提到迭代器,首先它是与集合相关的,集合可以看作是一个可以包含对象的容器。例如List,Set,Map,迭代器的作用就是把容器中的对象一个接一个地遍历出来。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import java.util.ArrayList;
import java.util.Iterator;
public class IteratorPattern {
public static void main(String[] args){
ArrayList<Integer> list = new ArrayList<>();
for(int i = 0 ;i < 11; ++i){
list.add(i);
}
Iterator it = list.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
}
}

迭代器的实现

迭代器模式的结构:

  1. 抽象容器,一般是一个接口, 提供一个iterator() 方法,如java中的Collection、List和Set等类的接口。
  2. 具体容器,容器的实现类 ,如ArrayList, LinkedList和HashSet等。
  3. 抽象迭代器, 定义遍历集合中的所需要的方法,一般包含三个方法。

>
next() 取得迭代器中准备的下一个元素
hasNext() 判断是否遍历结束
remove() 将迭代器的下一个元素移除

4.具体迭代器,实现抽象迭代器的方法。

抽象迭代器

1
2
3
4
5
interface MyIterator{
public Object next();
public boolean hasNext();
public void remove();
}

具体迭代器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
class ContreteIterator implements MyIterator{
private List list;
private int cursor;
public ContreteIterator(List list){
this.list = list;
cursor = 0;
}
@Override
public Object next(){
if(cursor != list.size()){
return list.get(cursor++);
}
return null;
}
@Override
public boolean hasNext(){
if(cursor == list.size()){
return false;
}
return true;
}
@Override
public void remove() {
if(cursor != list.size()){
list.remove(cursor);
}
}
}

抽象集合类

1
2
3
4
5
interface Container<T>{
public void add(T obj);
public void remove(T obj);
public MyIterator myIterator();
}

集合类的实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class ContreteContainer<T> implements Container<T>{
private List<T> list;
public ContreteContainer(){
list = new ArrayList<T>();
}
@Override
public void add(T obj){
list.add(obj);
}
@Override
public void remove(T obj){
list.remove(obj);
}
@Override
public MyIterator myIterator(){
return new ContreteIterator(this.list);
}
}

测试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class IteratorPattern {
public static void main(String[] args){
ContreteContainer<Integer> contreteContainer = new ContreteContainer<>();
for(int i = 1; i <= 10; ++i){
contreteContainer.add(i);
}
MyIterator it = contreteContainer.myIterator();
while(true){
if(it.hasNext()){
System.out.println(it.next());
}
if(it.hasNext()){
it.remove();
}
else{
break;
}
}
}
}

总结

优点:
对于hsah表来说,使用迭代器的遍历会变得简单。
可以提供正反两种方向的遍历顺序

缺点:
对于简单数组或者有序列表,用迭代器反而会比较麻烦。比如对ArrayList一般使用for循环和get进行遍历。