CPSC 210

D7: Iterator Pattern

Learning Goals

  • To apply the Iterator Design Pattern to a given problem

The Iterator Pattern

Teaching

Please

Evaluation

Iterator: Motivation

Joe

I have a collection of elements I don't know much about; but I know that there should be a "next element".

I want to access and traverse the collection's elements without exposing its implementation.

Intent: Provide a way to access the elements of an aggregate object sequentially without exposing its underlying implementation

We've been doing this!

...all term long...

for (Item next : collection) {
    // do something with next
}

...where collection was e.g. an ArrayList, LinkedList, HashSet of objects of type Item

  • This is just a short-hand syntax that was introduced in Java 5 (2004)
  • Before, it would
    look like...
Iterator<Item> itr = collection.iterator();
while (itr.hasNext()) {
  Item nextItem = itr.next();
  // do something with nextItem
}

Modification while Iterating

for (Item next : collection) {
  if ("Chickpeas".equals(next.getName())) {
    collection.remove(next);
  }
}

This doesn't work!

Iterator<Item> iterator = collection.iterator();
while (iterator.hasNext()) {
  Item next = iterator.next();
  if ("Chickpeas".equals(next.getName())) {
    iterator.remove();
  }
}

But this does!

Iterator in Java

  • For this code to compile, the collection must have:
Iterator<Item> itr = collection.iterator();
while (itr.hasNext()) {
  Item nextItem = itr.next();
  // do something with nextItem
}
Iterator<E> iterator();
  • And the iterator must have:
boolean hasNext();
E next();

Iterator Hierarchy

returns new ArrayListIterator<E>()
returns new LinkedListIterator<E>()
returns new HashSetIterator<E>()
ArrayListIterator<E>
LinkedListIterator<E>
HashSetIterator<E>

Iterable<E>

Iterator<E> iterator()

<<interface>>

Iterator<E>

boolean hasNext()
E next()
void remove()

<<interface>>

Collection

<<interface>>

List<E>

<<interface>>

LinkedList<E>

Iterator<E> iterator()

ArrayList<E>

Iterator<E> iterator()

HashSet<E>

Iterator<E> iterator()

Set<E>

<<interface>>

Applying Iterators

for (Item next : collection) {
    // do something with next
}
  1. What collection do you want to iterate over? That is your Iterable.
  2. What type of data do you want to iterate over?  That identifies the type parameter for the Iterable<Item> and Iterator<Item>
  3. Provide an implementation for the iterator() method.

Let's look at the lecture ticket as an example...

Thing doll = new Thing("Doll");
Thing puppy = new Thing("Puppy");
Thing marble = new Thing("Marble");

ThingCollection myThings = new ThingCollection();
myThings.add(doll);
myThings.add(puppy);
myThings.add(marble);

for(Thing thing : myThings) {  
  thing.display();
}

Not compiling:

foreach not applicable 
to type 'ThingCollection'
public class Thing {
  private String name;

  public Thing(String name) {
    this.name = name;
  }

  public void display() {
    System.out.println("Behold, 
    	the beautiful " + name);
  }
}

Your code

Thing

public class ThingCollection {
  private ArrayList<Thing> things = new ArrayList<>();

  public void add(Thing thing) {
    System.out.println("Ooh --- I have a new " + thing);
    things.add(thing);
  }
}

ThingCollection

  • Part 1: Which class would need to implement
    Iterable?
  • Part 2: What would be passed to Iterable as the type parameter?
  • Part 3: Where would the iterator() method be implemented?
  • Part 4: What would the iterator() method return?

ThingCollection

Thing

ThingCollection

things.iterator()

Lecture Lab

Things & Remote Controls

D7: Iterator Pattern

The End - Thank You!

Made with Slides.com