迭代器模式提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部的标示。其别名为游标(Cursor)。迭代器模式是一种对象行为型模式。
从定义可见,迭代器模式是为容器而生。很明显,对容器对象的访问必然涉及到遍历算法。你可以一股脑的将遍历方法塞到容器对象中去;或者根本不去提供什么遍历算法,让使用容器的人自己去实现去吧。这两种情况好像都能够解决问题。
然而在前一种情况,容器承受了过多的功能,它不仅要负责自己“容器”内的元素维护(添加、删除等等),而且还要提供遍历自身的接口;而且由于遍历状态保存的问题,不能对同一个容器对象同时进行多个遍历。第二种方式倒是省事,却又将容器的内部细节暴露无遗。
1) 迭代器角色(Iterator):迭代器角色负责定义访问和遍历元素的接口。
2) 具体迭代器角色(Concrete Iterator):具体迭代器角色要实现迭代器接口,并要记录遍历中的当前位置。
3) 容器角色(Container):容器角色负责提供创建具体迭代器角色的接口。
4) 具体容器角色(Concrete Container):具体容器角色实现创建具体迭代器角色的接口——这个具体迭代器角色于该容器的结构相关。
interface MyCollection { MyIterator createIterator(); } interface MyIterator { void first(); void next(); boolean isLast(); Object currentItem(); } class NewCollection implements MyCollection { private Object[] obj={"dog","pig","cat","monkey","pig"}; public MyIterator createIterator() { return new NewIterator(); } private class NewIterator implements MyIterator { private int currentIndex=0; public void first() { currentIndex=0; } public void next() { if(currentIndex<obj.length) { currentIndex++; } } public void previous() { if(currentIndex>0) { currentIndex--; } } public boolean isLast() { return currentIndex==obj.length; } public boolean isFirst() { return currentIndex==0; } public Object currentItem() { return obj[currentIndex]; } } } class Client { public static void process(MyCollection collection) { MyIterator i=collection.createIterator(); while(!i.isLast()) { System.out.println(i.currentItem().toString()); i.next(); } } public static void main(String a[]) { MyCollection collection=new NewCollection(); process(collection); } }代码二、JDK中 Iterator
import java.util.*; public class IteratorDemo { public static void process(Collection c) { Iterator i=c.iterator(); while(i.hasNext()) { System.out.println(i.next().toString()); } } public static void main(String args[]) { Collection list=new HashSet(); list.add("Cat"); list.add("Dog"); list.add("Pig"); list.add("Dog"); list.add("Monkey"); process(list); } }代码三、
public interface TVIterator { void setChannel(int i); void next(); void previous(); boolean isLast(); Object currentChannel(); boolean isFirst(); }
public interface Television { TVIterator createIterator(); }
public class TCLTelevision implements Television { private Object[] obj={"湖南卫视","北京卫视","上海卫视","湖北卫视","黑龙江卫视"}; public TVIterator createIterator() { return new TCLIterator(); } class TCLIterator implements TVIterator { private int currentIndex=0; public void next() { if(currentIndex<obj.length) { currentIndex++; } } public void previous() { if(currentIndex>0) { currentIndex--; } } public void setChannel(int i) { currentIndex=i; } public Object currentChannel() { return obj[currentIndex]; } public boolean isLast() { return currentIndex==obj.length; } public boolean isFirst() { return currentIndex==0; } } }
public class SkyworthTelevision implements Television { private Object[] obj={"CCTV-1","CCTV-2","CCTV-3","CCTV-4","CCTV-5","CCTV-6","CCTV-7","CCTV-8"}; public TVIterator createIterator() { return new SkyworthIterator(); } private class SkyworthIterator implements TVIterator { private int currentIndex=0; public void next() { if(currentIndex<obj.length) { currentIndex++; } } public void previous() { if(currentIndex>0) { currentIndex--; } } public void setChannel(int i) { currentIndex=i; } public Object currentChannel() { return obj[currentIndex]; } public boolean isLast() { return currentIndex==obj.length; } public boolean isFirst() { return currentIndex==0; } } }
import javax.xml.parsers.*; import org.w3c.dom.*; import org.xml.sax.SAXException; import java.io.*; public class XMLUtil { //该方法用于从XML配置文件中提取具体类类名,并返回一个实例对象 public static Object getBean() { try { //创建文档对象 DocumentBuilderFactory dFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = dFactory.newDocumentBuilder(); Document doc; doc = builder.parse(new File("config.xml")); //获取包含类名的文本节点 NodeList nl = doc.getElementsByTagName("className"); Node classNode=nl.item(0).getFirstChild(); String cName=classNode.getNodeValue(); //通过类名生成实例对象并将其返回 Class c=Class.forName(cName); Object obj=c.newInstance(); return obj; } catch(Exception e) { e.printStackTrace(); return null; } } }
<?xml version="1.0"?> <config> <className>SkyworthTelevision</className> </config>
public class Client { public static void display(Television tv) { TVIterator i=tv.createIterator(); System.out.println("电视机频道:"); while(!i.isLast()) { System.out.println(i.currentChannel().toString()); i.next(); } } public static void reverseDisplay(Television tv) { TVIterator i=tv.createIterator(); i.setChannel(5); System.out.println("逆向遍历电视机频道:"); while(!i.isFirst()) { i.previous(); System.out.println(i.currentChannel().toString()); } } public static void main(String a[]) { Television tv; tv=(Television)XMLUtil.getBean(); display(tv); System.out.println("--------------------------"); reverseDisplay(tv); } }
迭代器模式的缺点
java.util.Iterator
(thus among others also java.util.Scanner
!).java.util.Enumeration