在平时我们会遇到需要顺序访问一个对象集的元素的场景,比如:老师按照名单进行点名;去图书馆,在某一栏书架上从左到右或者从右到左查找想要借的书;又如开车的时候,想听音乐或者收音机电台,一个个地查找等等。
这种一个一个遍历的场景就是今天我们要讲的迭代器模式。在Java语言的聚集(Collection)框架中,广泛使用了迭代器来遍历聚集的元素。
意图
提供一种方法顺序访问一个聚合对象中各个元素,而不是暴露该对象的内部表示。
结构
迭代器模式的基本结构如下:
这里涉及到的参与者有如下几种:
以音乐播放为例来进行展示:
Iterator迭代器
package com.wangmengjun.tutorial.designpattern.iterator;
public interface MusicIterator {
boolean hasNext();
Music next();
}
Aggregate(聚合)
package com.wangmengjun.tutorial.designpattern.iterator;
public interface MusicCollection {
void add(Music entity);
void remove(Music entity);
MusicIterator iterator();
}
ConcreteAggregate(具体聚合)
package com.wangmengjun.tutorial.designpattern.iterator;
import java.util.ArrayList;
import java.util.List;
public class AudioPlayer implements MusicCollection {
private List<Music> musicList;
public AudioPlayer() {
musicList = new ArrayList<>();
}
@Override
public void add(Music entity) {
musicList.add(entity);
}
@Override
public void remove(Music entity) {
musicList.remove(entity);
}
@Override
public MusicIterator iterator() {
return new MusicIteratorImpl();
}
//ConcreteIterator(具体迭代器)
private class MusicIteratorImpl implements MusicIterator {
private int cursor;
@Override
public boolean hasNext() {
return cursor < AudioPlayer.this.musicList.size();
}
@Override
public Music next() {
Music music = AudioPlayer.this.musicList.get(cursor);
cursor++;
return music;
}
}
}
Music类
package com.wangmengjun.tutorial.designpattern.iterator;
public class Music {
private String name;
private String singer;
public Music(String name, String singer) {
super();
this.name = name;
this.singer = singer;
}
/**
* @return the name
*/
public String getName() {
return name;
}
/**
* @param name the name to set
*/
public void setName(String name) {
this.name = name;
}
/**
* @return the singer
*/
public String getSinger() {
return singer;
}
/**
* @param singer the singer to set
*/
public void setSinger(String singer) {
this.singer = singer;
}
@Override
public String toString() {
return "Music [name=" + name + ", singer=" + singer + "]";
}
}
测试一下:
package com.wangmengjun.tutorial.designpattern.iterator;
public class Main {
public static void main(String[] args) {
MusicCollection musicList = new AudioPlayer();
musicList.add(new Music("吻別","张学友"));
musicList.add(new Music("忘情水","刘德华"));
musicList.add(new Music("过火","张信哲"));
musicList.add(new Music("阳光总在风雨后","许美静"));
/**
* Music [name=吻別, singer=张学友]
Music [name=忘情水, singer=刘德华]
Music [name=过火, singer=张信哲]
Music [name=阳光总在风雨后, singer=许美静]
*/
MusicIterator iterator = musicList.iterator();
while(iterator.hasNext()) {
Music elem = iterator.next();
System.out.println(elem);
}
}
}
输出結果:
Music [name=吻別, singer=张学友]
Music [name=忘情水, singer=刘德华]
Music [name=过火, singer=张信哲]
Music [name=阳光总在风雨后, singer=许美静]
这样,一个简单的迭代器模式示例就完成了。
优缺点
优点:
public ListIterator<E> listIterator(int index) {
rangeCheckForAdd(index);
return new ListItr(index);
}
/**
* Returns a list iterator over the elements in this list (in proper
* sequence).
*
* <p>The returned list iterator is <a href="#fail-fast"><i>fail-fast</i></a>.
*
* @see #listIterator(int)
*/
public ListIterator<E> listIterator() {
return new ListItr(0);
}
public Iterator<E> iterator() {
return new Itr();
}
/**
* An optimized version of AbstractList.Itr
*/
private class Itr implements Iterator<E> {
int cursor; // index of next element to return
... ...
}
/**
* An optimized version of AbstractList.ListItr
*/
private class ListItr extends Itr implements ListIterator<E> {
... ...
}
缺点:
参考
[1]. 阎宏. Java与模式.电子工业出版社
[2]. Erich Gamma. 设计模式-可复用面向对象软件的基础. 机械工业出版社.