Iterator

Introduction

One of the most common data structures in software development is what is generic called a collection. A collection is just a grouping of some objects. They can have the same type or they can be all casted to a base type like object. A collection can bes a list, an array, a tree and the examples can continue.

What is important is that the collection provides a way to access its elements without expose their internal structure. So that, we shoud hava a mechanism to traverse a list or an array in the same way, when it doesn’t matter they are internally represented.

Definition

Provide a way to access the elements of an aggregate object sequentially without exposing its underlying representation.

UML class

Iterator Pattern

Participants

  • Iterator
    • defines an interface for accessing and traversing elements.
  • ConcreteIterator
    • implements the Iterator interface.
    • keeps track of the current position in the traversal of the aggregate.
  • Aggregate
    • defines an interface for creating an Iterator object.
  • ConcreteAggregate
    • implements the Iterator creation interface to return an instance of the proper ConcreteIterator.

Example


/**
 * Iterator interface.
 * @author 	lofei
 * @date   	Mar.29 2014
 * @version 1.0.0
 * @email	lofei@lofei.info
 */
public interface Iterator {
	/**
	 * return the first element of an collection.
	 * @return the first element
	 */
	public Object first();
	
	/**
	 * return the next element in the iteration
	 * @return
	 */
	public Object next();
	
	/**
	 * returns {@code true} if the iteration has more elements.
	 * @return {@code true} when more element is available.
	 */
	public boolean hasNext();	
}

/**
 * The interface of the Aggregate
 * @author 	lofei
 * @date   	Mar.29 2014
 * @version 1.0.0
 * @email	lofei@lofei.info
 */
public interface Container {
	/**
	 * Create an {@link Iterator} object.
	 * @return The Iterator object.
	 */
	public Iterator iterator();
}


/**
 * The ConcreteAggregate class.
 * @author 	lofei
 * @date   	Mar.29 2014
 * @version 1.0.0
 * @email	lofei@lofei.info
 */
public class BooksContainer implements Container {
	
	private String[] mTitles= {"Design patterns", "Journal to West",  "Cloud Atlas", "Harry's leaves"};
	
	
	@Override
	public Iterator iterator() {
		// TODO Auto-generated method stub
		return new BooksIterator();
	}

	/**
	 * ConcreteIterator.
	 * @author 	lofei
	 * @date   	Mar.29 2014
	 * @version 1.0.0
	 * @email	lofei@lofei.info
	 */
	private class BooksIterator implements Iterator{
		
		private int mPosition;

		@Override
		public Object first() {
			// return the first elements of the Aggregate
			return mTitles[0];
		}

		@Override
		public Object next() {
			// return the next elements
			if(hasNext()) {
				return mTitles[mPosition++];
			}
			return null;
		}

		@Override
		public boolean hasNext() {
			if(mPosition < mTitles.length)
				return true;
			return false;
		}
		
	}
}


/**
 * The client of the Iterator pattern.
 * @author 	lofei
 * @date   	Mar.29 2014
 * @version 1.0.0
 * @email	lofei@lofei.info
 */
public class Test {

	public static void main(String[] args) {
		Container booksContainer = new BooksContainer();
		for(Iterator it=booksContainer.iterator(); it.hasNext();) {
			String item = (String) it.next();
			System.out.println(item);
		}
		
	}

}

Output:

Design patterns
Journal to West
Cloud Atlas
Harry's leaves

Usage

  • When you want to access an aggregate object’s contents without exposing its internal representation.
  • When you want to supports multiple traversals of aggregate objects.
  • When you want to provide a uniform interface for traversing different aggregate structures(that is, to support polymorphic iteration).

See Also

blog comments powered by Disqus