`

管理好聚集——迭代子(Iterator)模式

 
阅读更多
java设计模式迭代子
迭代子模式为遍历聚集提供了统一的接口方法,从而使得客户端不需要知道聚集的内部结构就能就能对聚集进行遍历等操作。

迭代子模式的结构 :

一般结构:




涉及到的角色解释:

抽象迭代子(Iterator)角色:定义了遍历聚集的接口。

具体迭代子(ListIterator)角色:实现了抽象迭代子接口。

抽象聚集(Collection)角色:定义聚集的公共方法,并为聚集创建迭代子(Iterator)对象。

具体聚集(ArrayList)角色:能够返回一个实现迭代子(Iterator)接口的迭代子实例。

客户端(Client)角色:持有对聚集和迭代子实例的引用,通过迭代子对聚集进行迭代。

一个例子:

类图:




抽象迭代子(Iterator)角色:



Java代码 
package oliver.designpattern.iterator;  
/** 
* <b>迭代器接口。</b> 
* <p><b>详细说明:</b></p> 
* <!-- 在此添加详细说明 --> 
* 无。 
* <p><b>修改列表:</b></p> 
* <table width="100%" cellSpacing=1 cellPadding=3 border=1> 
* <tr bgcolor="#CCCCFF"><td>序号</td><td>作者</td><td>修改日期</td><td>修改内容</td></tr> 
* <!-- 在此添加修改列表,参考第一行内容 --> 
* <tr><td>1</td><td>Oliver</td><td>May 14, 2010 9:30:38 AM</td><td>建立类型</td></tr> 
*  
* </table> 
* @version 1.0 
* @author Oliver 
* @since 1.0 
*/ 
public interface Iterator  
{  
    /** 
     * <b>指针移动到聚集开头。</b>   
     * <p><b>详细说明:</b></p> 
     * <!-- 在此添加详细说明 --> 
     * 无。 
     */ 
    void first();  
    /** 
     * <b>获取当前指针指向的元素。</b>   
     * <p><b>详细说明:</b></p> 
     * <!-- 在此添加详细说明 --> 
     * 无。 
     * @return 
     */ 
    Object next();  
    /** 
     * <b>是否有下一个元素。</b>   
     * <p><b>详细说明:</b></p> 
     * <!-- 在此添加详细说明 --> 
     * 无。 
     * @return 
     */ 
    boolean hasNext();  


package oliver.designpattern.iterator;
/**
* <b>迭代器接口。</b>
* <p><b>详细说明:</b></p>
* <!-- 在此添加详细说明 -->
* 无。
* <p><b>修改列表:</b></p>
* <table width="100%" cellSpacing=1 cellPadding=3 border=1>
* <tr bgcolor="#CCCCFF"><td>序号</td><td>作者</td><td>修改日期</td><td>修改内容</td></tr>
* <!-- 在此添加修改列表,参考第一行内容 -->
* <tr><td>1</td><td>Oliver</td><td>May 14, 2010 9:30:38 AM</td><td>建立类型</td></tr>
*
* </table>
* @version 1.0
* @author Oliver
* @since 1.0
*/
public interface Iterator
{
/**
* <b>指针移动到聚集开头。</b> 
* <p><b>详细说明:</b></p>
* <!-- 在此添加详细说明 -->
* 无。
*/
void first();
/**
* <b>获取当前指针指向的元素。</b> 
* <p><b>详细说明:</b></p>
* <!-- 在此添加详细说明 -->
* 无。
* @return
*/
Object next();
/**
* <b>是否有下一个元素。</b> 
* <p><b>详细说明:</b></p>
* <!-- 在此添加详细说明 -->
* 无。
* @return
*/
boolean hasNext();
}
 


具体迭代子(ListIterator)角色:



Java代码 
package oliver.designpattern.iterator;  
public class ListIterator implements Iterator  
{  
    private Collection collection;  
      
    private int index=0;  
      
    private int size=0;  
      
    public ListIterator(Collection collection)  
    {  
        this.collection=collection;  
        size=collection.size();  
    }  
    /**  
     * <b>获取聚集中当前指针指向的元素。</b>   
     * @see oliver.designpattern.iterator.Iterator#next() 
     */ 
    public Object next()  
    {  
        return collection.getElement(index++);  
    }  
    /**  
     * <b>指针移动到聚集的开头。</b>   
     * @see oliver.designpattern.iterator.Iterator#first() 
     */ 
    public void first()  
    {  
        index=0;  
    }  
    /**  
     * <b>是否有下一个元素。</b>   
     * @see oliver.designpattern.iterator.Iterator#hasNext() 
     */ 
    public boolean hasNext()  
    {  
        return index<size;  
    }  


package oliver.designpattern.iterator;
public class ListIterator implements Iterator
{
private Collection collection;

private int index=0;

private int size=0;

public ListIterator(Collection collection)
{
this.collection=collection;
size=collection.size();
}
/**
* <b>获取聚集中当前指针指向的元素。</b> 
* @see oliver.designpattern.iterator.Iterator#next()
*/
public Object next()
{
return collection.getElement(index++);
}
/**
* <b>指针移动到聚集的开头。</b> 
* @see oliver.designpattern.iterator.Iterator#first()
*/
public void first()
{
index=0;
}
/**
* <b>是否有下一个元素。</b> 
* @see oliver.designpattern.iterator.Iterator#hasNext()
*/
public boolean hasNext()
{
return index<size;
}
}
 


抽象聚集(Collection)角色:


Java代码 
package oliver.designpattern.iterator;  
/** 
* <b>抽象聚集类。</b> 
* <p><b>详细说明:</b></p> 
* <!-- 在此添加详细说明 --> 
* 无。 
* <p><b>修改列表:</b></p> 
* <table width="100%" cellSpacing=1 cellPadding=3 border=1> 
* <tr bgcolor="#CCCCFF"><td>序号</td><td>作者</td><td>修改日期</td><td>修改内容</td></tr> 
* <!-- 在此添加修改列表,参考第一行内容 --> 
* <tr><td>1</td><td>Oliver</td><td>May 14, 2010 9:27:47 AM</td><td>建立类型</td></tr> 
*  
* </table> 
* @version 1.0 
* @author Oliver 
* @since 1.0 
*/ 
public abstract class Collection  
{  
    /** 
     * <b>工厂方法:。</b>   
     * <p><b>详细说明:</b></p> 
     * <!-- 在此添加详细说明 --> 
     * 无。 
     * @return 一个迭代子 
     */ 
    public abstract Iterator iterator();  
      
    /** 
     * <b>获取聚集大小。</b>   
     * <p><b>详细说明:</b></p> 
     * <!-- 在此添加详细说明 --> 
     * 无。 
     * @return 
     */ 
    public abstract int size();  
      
    /** 
     * <b>获取集合元素。</b>   
     * <p><b>详细说明:</b></p> 
     * <!-- 在此添加详细说明 --> 
     * 无。 
     * @param index 
     * @return 
     */ 
    public abstract Object getElement(int index);  


package oliver.designpattern.iterator;
/**
* <b>抽象聚集类。</b>
* <p><b>详细说明:</b></p>
* <!-- 在此添加详细说明 -->
* 无。
* <p><b>修改列表:</b></p>
* <table width="100%" cellSpacing=1 cellPadding=3 border=1>
* <tr bgcolor="#CCCCFF"><td>序号</td><td>作者</td><td>修改日期</td><td>修改内容</td></tr>
* <!-- 在此添加修改列表,参考第一行内容 -->
* <tr><td>1</td><td>Oliver</td><td>May 14, 2010 9:27:47 AM</td><td>建立类型</td></tr>
*
* </table>
* @version 1.0
* @author Oliver
* @since 1.0
*/
public abstract class Collection
{
/**
* <b>工厂方法:。</b> 
* <p><b>详细说明:</b></p>
* <!-- 在此添加详细说明 -->
* 无。
* @return 一个迭代子
*/
public abstract Iterator iterator();

/**
* <b>获取聚集大小。</b> 
* <p><b>详细说明:</b></p>
* <!-- 在此添加详细说明 -->
* 无。
* @return
*/
public abstract int size();

/**
* <b>获取集合元素。</b> 
* <p><b>详细说明:</b></p>
* <!-- 在此添加详细说明 -->
* 无。
* @param index
* @return
*/
public abstract Object getElement(int index);
}
 
具体聚集(ArrayList)角色:


Java代码 
package oliver.designpattern.iterator;  
public class ArrayList extends Collection  
{  
    /** 
     * 聚集数据。 
     */ 
    private Object[] items = new Object[10];  
      
    /** 
     * 当前指针。 
     */ 
    private int currentIndex=0;  
      
    /** 
     * <b>向聚集中添加元素。</b>   
     * <p><b>详细说明:实现了聚集大小自动增长</b></p> 
     * <!-- 在此添加详细说明 --> 
     * 无。 
     * @param item 
     */ 
    public void add(Object item)  
    {  
        if(currentIndex>=items.length)  
        {  
            Object[] newItems = new Object[items.length+10];   
            System.arraycopy(items,0,newItems,0,items.length);  
            items=newItems;  
        }  
        items[currentIndex]=item;  
        currentIndex++;  
    }  
      
    /**  
     * <b>iterator。</b>   
     * @see oliver.designpattern.iterator.Collection#iterator() 
     */ 
    @Override 
    public Iterator iterator()  
    {  
          
        return new ListIterator(this);  
    }  
    /** 
     * <b>获取聚集大小。</b>   
     * <p><b>详细说明:</b></p> 
     * <!-- 在此添加详细说明 --> 
     * 无。 
     * @return 
     */ 
    public int size()  
    {  
        return items.length;  
    }  
    public Object getElement(int index)  
    {  
        if(index<items.length)  
            return items[index];  
        else 
            throw new IndexOutOfBoundsException();  
    }  


package oliver.designpattern.iterator;
public class ArrayList extends Collection
{
/**
* 聚集数据。
*/
private Object[] items = new Object[10];

/**
* 当前指针。
*/
private int currentIndex=0;

/**
* <b>向聚集中添加元素。</b> 
* <p><b>详细说明:实现了聚集大小自动增长</b></p>
* <!-- 在此添加详细说明 -->
* 无。
* @param item
*/
public void add(Object item)
{
if(currentIndex>=items.length)
{
Object[] newItems = new Object[items.length+10];
System.arraycopy(items,0,newItems,0,items.length);
items=newItems;
}
items[currentIndex]=item;
currentIndex++;
}

/**
* <b>iterator。</b> 
* @see oliver.designpattern.iterator.Collection#iterator()
*/
@Override
public Iterator iterator()
{

return new ListIterator(this);
}
/**
* <b>获取聚集大小。</b> 
* <p><b>详细说明:</b></p>
* <!-- 在此添加详细说明 -->
* 无。
* @return
*/
public int size()
{
return items.length;
}
public Object getElement(int index)
{
if(index<items.length)
return items[index];
else
throw new IndexOutOfBoundsException();
}
}
 
客户端(Client)角色:


Java代码 
package oliver.designpattern.iterator;  
import junit.framework.TestCase;  
public class ExternalIteratorTest extends TestCase  
{  
    /** 
     * <b>外禀迭代子测试。</b>   
     * <p><b>详细说明:</b></p> 
     * <!-- 在此添加详细说明 --> 
     * 无。 
     */ 
    public void testExternalIterator()  
    {  
        ArrayList list = new ArrayList();  
        for(int i=0;i<10;i++)  
            list.add(i);  
        Iterator it=list.iterator();  
        while(it.hasNext())  
        {  
            System.out.println(it.next());  
        }  
    }  


package oliver.designpattern.iterator;
import junit.framework.TestCase;
public class ExternalIteratorTest extends TestCase
{
/**
* <b>外禀迭代子测试。</b> 
* <p><b>详细说明:</b></p>
* <!-- 在此添加详细说明 -->
* 无。
*/
public void testExternalIterator()
{
ArrayList list = new ArrayList();
for(int i=0;i<10;i++)
list.add(i);
Iterator it=list.iterator();
while(it.hasNext())
{
System.out.println(it.next());
}
}
}
 
内禀子,外禀子?

内禀子:聚集本身不提供访问其内部元素的方法,只有通过聚集内部的迭代子来遍历聚集,这时迭代子是个内部类,是聚集的一部分。

外禀子:聚集本身提供访问其内部元素的方法,可以通过外部的迭代子来遍历聚集,这时迭代子是个外部类,只维持对聚集的一个引用。

显然,我们上面的例子是一个外禀迭代。

java内部的ArrayList类用的是一个内禀子迭代子。

在jdk中,ArrayList类继承抽象类AbstractList,而在AbstractList中,有一个内部类Itr:


Java代码 
private class Itr implements Iterator<E> {  
/** 
* Index of element to be returned by subsequent call to next. 
*/ 
int cursor = 0;  
/** 
* Index of element returned by most recent call to next or 
* previous.  Reset to -1 if this element is deleted by a call 
* to remove. 
*/ 
int lastRet = -1;  
/** 
* The modCount value that the iterator believes that the backing 
* List should have.  If this expectation is violated, the iterator 
* has detected concurrent modification. 
*/ 
int expectedModCount = modCount;  
public boolean hasNext() {  
           return cursor != size();  
}  
public E next() {  
           checkForComodification();  
    try {  
    E next = get(cursor);  
    lastRet = cursor++;  
    return next;  
    } catch (IndexOutOfBoundsException e) {  
    checkForComodification();  
    throw new NoSuchElementException();  
    }  
}  
public void remove() {  
    if (lastRet == -1)  
    throw new IllegalStateException();  
           checkForComodification();  
    try {  
    AbstractList.this.remove(lastRet);  
    if (lastRet < cursor)  
        cursor--;  
    lastRet = -1;  
    expectedModCount = modCount;  
    } catch (IndexOutOfBoundsException e) {  
    throw new ConcurrentModificationException();  
    }  
}  
final void checkForComodification() {  
    if (modCount != expectedModCount)  
    throw new ConcurrentModificationException();  
}  
   }  
   private class ListItr extends Itr implements ListIterator<E> {  
ListItr(int index) {  
    cursor = index;  
}  
public boolean hasPrevious() {  
    return cursor != 0;  
}  
       public E previous() {  
           checkForComodification();  
           try {  
               int i = cursor - 1;  
               E previous = get(i);  
               lastRet = cursor = i;  
               return previous;  
           } catch (IndexOutOfBoundsException e) {  
               checkForComodification();  
               throw new NoSuchElementException();  
           }  
       }  
public int nextIndex() {  
    return cursor;  
}  
public int previousIndex() {  
    return cursor-1;  
}  
public void set(E e) {  
    if (lastRet == -1)  
    throw new IllegalStateException();  
           checkForComodification();  
    try {  
    AbstractList.this.set(lastRet, e);  
    expectedModCount = modCount;  
    } catch (IndexOutOfBoundsException ex) {  
    throw new ConcurrentModificationException();  
    }  
}  
public void add(E e) {  
           checkForComodification();  
    try {  
    AbstractList.this.add(cursor++, e);  
    lastRet = -1;  
    expectedModCount = modCount;  
    } catch (IndexOutOfBoundsException ex) {  
    throw new ConcurrentModificationException();  
    }  
}  
   } 

private class Itr implements Iterator<E> {
/**
* Index of element to be returned by subsequent call to next.
*/
int cursor = 0;
/**
* Index of element returned by most recent call to next or
* previous.  Reset to -1 if this element is deleted by a call
* to remove.
*/
int lastRet = -1;
/**
* The modCount value that the iterator believes that the backing
* List should have.  If this expectation is violated, the iterator
* has detected concurrent modification.
*/
int expectedModCount = modCount;
public boolean hasNext() {
            return cursor != size();
}
public E next() {
            checkForComodification();
    try {
E next = get(cursor);
lastRet = cursor++;
return next;
    } catch (IndexOutOfBoundsException e) {
checkForComodification();
throw new NoSuchElementException();
    }
}
public void remove() {
    if (lastRet == -1)
throw new IllegalStateException();
            checkForComodification();
    try {
AbstractList.this.remove(lastRet);
if (lastRet < cursor)
    cursor--;
lastRet = -1;
expectedModCount = modCount;
    } catch (IndexOutOfBoundsException e) {
throw new ConcurrentModificationException();
    }
}
final void checkForComodification() {
    if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
    }
    private class ListItr extends Itr implements ListIterator<E> {
ListItr(int index) {
    cursor = index;
}
public boolean hasPrevious() {
    return cursor != 0;
}
        public E previous() {
            checkForComodification();
            try {
                int i = cursor - 1;
                E previous = get(i);
                lastRet = cursor = i;
                return previous;
            } catch (IndexOutOfBoundsException e) {
                checkForComodification();
                throw new NoSuchElementException();
            }
        }
public int nextIndex() {
    return cursor;
}
public int previousIndex() {
    return cursor-1;
}
public void set(E e) {
    if (lastRet == -1)
throw new IllegalStateException();
            checkForComodification();
    try {
AbstractList.this.set(lastRet, e);
expectedModCount = modCount;
    } catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
    }
}
public void add(E e) {
            checkForComodification();
    try {
AbstractList.this.add(cursor++, e);
lastRet = -1;
expectedModCount = modCount;
    } catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
    }
}
    } 
内禀子VS外禀子

迭代子有一个很重要的属性就是当前聚集的指针,有了当前的指针,才能进行迭代。如果几个客户端同时迭代一个聚集,假如聚集的迭代子是外禀子,这个是没有问题的,几个客户端持有每个外禀子的独立指针。但是如果聚集的迭代子是内禀子,问题就出现了:几个客户端同时持有内禀子的指针,并且同时对指针进行操作,就不能正常的对集合进行遍历。

使用外禀迭代子的一个重要理由是它可以被几个不同的方法和对象共享和控制,使用内禀子的优点是它不破坏对聚集的封装。

java的设计师在设计AbstractList的时候在聚集定义了内部类Itr作为迭代子,也就是说,设计师不希望客户端随意更换迭代子。

项目源码下载:http://cid-2c8a0dc7c1eb1d71.skydrive.live.com/self.aspx/soft/Design%20Pattern/Iterator.7z

分享到:
评论

相关推荐

    IteratorPattern 迭代设计模式

    迭代器模式(IteratorPattern)是设计模式中的一种行为模式,它提供了一种顺序访问聚合对象元素的方法,同时又不暴露其底层表示。这种模式允许我们遍历集合对象的元素,而无需暴露其内部结构。在Java、C#等面向对象...

    设计模式(C#)之迭代器模式(Iterator Pattern)

    通过理解迭代器模式,开发者可以更好地组织代码,提高代码的可读性和可维护性,同时降低耦合度。在C#开发中,利用内置的`IEnumerable`和`IEnumerator`接口可以轻松地实现迭代器模式,为各种聚合数据结构提供流畅的...

    迭代器Iterator.txt

    根据提供的文件信息,我们可以深入探讨迭代器(Iterator)这一设计模式在Java中的应用与实现细节。迭代器模式是一种常用的设计模式,它允许我们以一种顺序访问集合对象的方式遍历其元素,而无需暴露该对象的内部表示...

    (行为型模式) Iterator 迭代器模式

    C#面向对象设计模式 (行为型模式) Iterator 迭代器模式 视频讲座下载

    详解Java设计模式——迭代器模式

    详解Java设计模式——迭代器模式 迭代器模式是Java设计模式的一种,主要用于解决聚合对象的遍历问题。该模式提供了一种方法顺序访问一个聚合对象中的各个元素,而又无须暴露该对象的内部表示。通过使用迭代器模式,...

    设计模式之迭代器模式(Iterator)

    例如,在Java中,`Iterable`接口和`Iterator`接口就是实现迭代器模式的关键。`Iterable`接口定义了获取迭代器的方法`iterator()`,而`Iterator`接口提供了`hasNext()`和`next()`方法,分别用于检查是否还有下一个...

    Iterator Pattern(迭代模式)

    其他文件如`.classpath`、`.project`、`build.xml`、`Workspace.sws`等是Eclipse项目配置文件,它们与迭代模式的理论知识关系不大,主要用于项目的构建和管理。 ### 总结 迭代模式是设计模式中的重要成员,它简化了...

    【Java设计模式】(1)迭代器模式Iterator

    迭代器模式(Iterator Pattern)是Java设计模式中的行为模式之一,它提供了一种方法来顺序访问聚合对象的元素,而又不暴露其底层表示。在Java中,迭代器模式被广泛应用于集合类,如ArrayList、LinkedList等,通过...

    设计模式(十七)——迭代器模式(Iterator Pattern)

    迭代器模式(Iterator Pattern) 基本介绍 迭代器模式,提供一种遍历集合元素的统一接口,用一致的方法遍历集合元素,不需要知道集合对象的底层表示,即:不暴露其内部的结构。 提供一种可以遍历聚合对象的方式。又...

    Java源码分析:深入探讨Iterator模式

    为了遍历这些容器中的元素,Java引入了迭代器模式(Iterator Pattern),这是一种常用的设计模式,它提供了一种访问聚合对象的方法,而无需暴露其内部表示。本文将详细解析Iterator模式在Java中的实现原理,并通过...

    Iterator迭代器讲解

    ### Iterator迭代器详解 #### 一、Iterator简介与概念 在Java编程语言中,`Iterator`接口是一个重要的组件,它提供了遍历集合的基本方法。`Iterator`的主要作用是在不暴露集合内部结构的情况下,顺序访问集合中的...

    迭代器iterator在opencv中使用

    迭代器iterator可以很方便的遍历所有元素。Mat类支持迭代器的方式对矩阵元素进行遍历。由于使用迭代器就不需要再使用行列数进行操作。

    迭代器模式(Iterator)C++实现

    迭代器模式是一种设计模式,它提供了一种方法来顺序访问聚合对象的元素,而又不暴露其底层表示。在C++中,迭代器模式通常通过定义一个接口,该接口允许访问和遍历聚合对象的元素,而无需暴露其内部结构。这种模式在...

    23钟设计模式之迭代器模式模式

    在迭代器模式中,存在三个主要角色:迭代器(Iterator)、聚合对象(Aggregate)和客户端(Client)。迭代器负责遍历聚合对象中的元素,聚合对象提供了元素的集合,而客户端则使用迭代器来遍历聚合对象中的元素。 ...

    迭代器模式(Iterator Pattern)原理图

    迭代器模式(Iterator Pattern)是设计模式中的一种行为模式,它允许顺序访问一个聚合对象中的各个元素,而又不需要暴露该对象的内部表示。迭代器模式提供了一种方法,可以顺序地访问一个聚合对象中的各个元素,而又...

    设计模式C++学习之迭代器模式(Iterator)

    迭代器模式是软件设计模式中的行为模式之一,它在C++编程中有着广泛的应用。这个模式提供了一种方法来顺序访问聚合对象的元素,而无需暴露其底层表示。通过迭代器,用户可以遍历集合中的所有元素,而无需知道如何...

    Iterator迭代器的用法

    该文档是演示迭代器Iterator的使用方法和源代码,其中包括了Iterator的继承类的讲解和再Iterator中的两种方法

    iterator-demo 迭代器设计模式demo

    这个“iterator-demo”应该是一个示例项目,用于演示如何在实际编程中应用迭代器模式。下面我们将深入探讨迭代器模式及其在IT领域的应用。 迭代器模式的核心思想是为集合类提供一种统一的访问方式,使得客户代码...

    Android编程设计模式之迭代器模式详解

    迭代器模式是指在客户访问类与容器体之间插入了一个第三者——迭代器,以解决容器类承担了过多的功能和遍历状态的存储问题。迭代器模式可以让容器类专注于维护自身内部的数据元素,而将遍历的方法封装在迭代器中,...

Global site tag (gtag.js) - Google Analytics