Iterator

From CSSEMediaWiki
(Difference between revisions)
Jump to: navigation, search
(New page: An Iterator is a way to step over each element in a collection. In JAVA, it is sometimes quicker to use the use for-each loop, but Iterators are still needed in some cases. The Iterator de...)
 
m (Reverted edits by Ebybymic (Talk); changed back to last version by Benjamin Gibson)
 
(15 intermediate revisions by 7 users not shown)
Line 1: Line 1:
An Iterator is a way to step over each element in a collection. In JAVA, it is sometimes quicker to use the use for-each loop, but Iterators are still needed in some cases. The Iterator design in JAVA is arguably broken, see [[Command query separation]].
+
[[Category:Design Patterns]]
 +
[[Category:Behavioural Patterns]]
 +
An Iterator is a way to step over each element in a collection without exposing the collection's underlying representation to clients. The Iterator pattern features heavily in the Java Collections API. Note that the Iterator design in Java is arguably broken - see [[Command query separation]].
  
== Examples ==
+
==Use When==
 +
Use the Iterator pattern when:
 +
*You want to access the contents of a collection sequentially without exposing the collection's underlying representation to clients.
 +
*You want to support multiple traversals of a collection.
 +
*You want to provide the same interface for traversing different collections.
  
A simple use of an Iterator to print out all names in a collection in JAVA:
+
==Structure==
 +
 
 +
[[image: IteratorStructure.png]]
 +
 
 +
==Participants==
 +
 
 +
===Iterator===
 +
Iterator defines the interface for accessing elements and traversing the collection.
 +
 
 +
===ConcreteIterator===
 +
ConcreteIterator implements in interface defined by Iterator. It keeps track of the current position of the traversal in the collection.
 +
 
 +
===Aggregate===
 +
Aggregate defines an interface for creating an iterator for itself.
 +
 
 +
===ConcreteAggregate===
 +
ConcreteAggregate implements the operation to create an iterator by returning an instance of ConcreteIterator.
 +
 
 +
== Usage Examples in Java Collections ==
 +
 
 +
A simple use of an Iterator to print out all names in a collection in Java:
  
 
  Collection<String> names = new HashSet<String>();
 
  Collection<String> names = new HashSet<String>();
Line 13: Line 39:
 
  }
 
  }
  
The for-each loop in JAVA can perform the same task, in a somewhat neater fashion (syntactically):
+
The for-each loop in Java can perform the same task, with somewhat neater syntax (although it should be noted that the Iterator is being used behind the scenes):
  
 
  Collection<String> names = new HashSet<String>();
 
  Collection<String> names = new HashSet<String>();
Line 32: Line 58:
 
  }
 
  }
  
This valid looking code will throw a ConcurrentModificationException, as directly removing an element from a collection while stepping through the collection could cause the code to "get lost". In this example, an Iterator should be used:
+
This valid looking code will throw a ConcurrentModificationException, as directly removing an element from a collection while stepping through the collection will cause the iterator to become invalid. In this example, an explicit iterator should be used:
  
 
  Collection<String> names = new HashSet<String>();
 
  Collection<String> names = new HashSet<String>();
Line 44: Line 70:
 
   }
 
   }
 
  }
 
  }
 +
 +
The remove() method on the iterator itself allows the item to be deleted without invalidating the iterator.
 +
 +
==Consequences==
 +
*The Iterator pattern makes it easy to define several different ways to traverse a collection by simply adding Iterator subclasses. In this way, you can add multiple iterators for the same collection or iterators for several different collections which have the same interface.
 +
*The Iterator pattern simplifies the Aggregate interface because it encapsulates all the traversal behavior.
 +
*The Iterator pattern allows more than one traversal of a single collection at the same time.
 +
*Violates the [[Dependency inversion principle]]
 +
 +
==Related Patterns==
 +
*[[Composite]]: Iterator is useful for traversing recursive structures like composites.
 +
*[[Factory Method]]: Polymorphic iterators require a factory method to ensure that the correct iterator is created.
 +
*[[Memento]]: This pattern is often used by iterators to capture the state of a traversal. The iterator often stores the [[Memento]] internally rather than using a separate Caretaker.
 +
*[[Tell, don't ask]]: Iterator uses tell, don't ask for navigation (but still requires Ask for extracting objects from the collection).
 +
 +
{{design patterns}}

Latest revision as of 03:22, 25 November 2010

An Iterator is a way to step over each element in a collection without exposing the collection's underlying representation to clients. The Iterator pattern features heavily in the Java Collections API. Note that the Iterator design in Java is arguably broken - see Command query separation.

Contents

Use When

Use the Iterator pattern when:

  • You want to access the contents of a collection sequentially without exposing the collection's underlying representation to clients.
  • You want to support multiple traversals of a collection.
  • You want to provide the same interface for traversing different collections.

Structure

IteratorStructure.png

Participants

Iterator

Iterator defines the interface for accessing elements and traversing the collection.

ConcreteIterator

ConcreteIterator implements in interface defined by Iterator. It keeps track of the current position of the traversal in the collection.

Aggregate

Aggregate defines an interface for creating an iterator for itself.

ConcreteAggregate

ConcreteAggregate implements the operation to create an iterator by returning an instance of ConcreteIterator.

Usage Examples in Java Collections

A simple use of an Iterator to print out all names in a collection in Java:

Collection<String> names = new HashSet<String>();
...
Iterator<String> myIterator = names.iterator();
while(myIterator.hasNext()) {
  String name = myIterator.next();
  System.out.println(name);
}

The for-each loop in Java can perform the same task, with somewhat neater syntax (although it should be noted that the Iterator is being used behind the scenes):

Collection<String> names = new HashSet<String>();
...
for(String name : names) {
  System.out.println(name);
}

However, consider the following example:

Collection<String> names = new HashSet<String>();
...
public void removeNames(String lastName) {
  for(String name : names) {
    if(name > lastName)
      names.remove(name);
  }
}

This valid looking code will throw a ConcurrentModificationException, as directly removing an element from a collection while stepping through the collection will cause the iterator to become invalid. In this example, an explicit iterator should be used:

Collection<String> names = new HashSet<String>();
...
public void removeNames(String lastName) {
  Iterator<String> myIterator = names.iterator();
  while(myIterator.hasNext()) {
    String name = myIterator.next();
    if(name > lastName)
      myIterator.remove();
  }
}

The remove() method on the iterator itself allows the item to be deleted without invalidating the iterator.

Consequences

  • The Iterator pattern makes it easy to define several different ways to traverse a collection by simply adding Iterator subclasses. In this way, you can add multiple iterators for the same collection or iterators for several different collections which have the same interface.
  • The Iterator pattern simplifies the Aggregate interface because it encapsulates all the traversal behavior.
  • The Iterator pattern allows more than one traversal of a single collection at the same time.
  • Violates the Dependency inversion principle

Related Patterns

  • Composite: Iterator is useful for traversing recursive structures like composites.
  • Factory Method: Polymorphic iterators require a factory method to ensure that the correct iterator is created.
  • Memento: This pattern is often used by iterators to capture the state of a traversal. The iterator often stores the Memento internally rather than using a separate Caretaker.
  • Tell, don't ask: Iterator uses tell, don't ask for navigation (but still requires Ask for extracting objects from the collection).


Personal tools