CPSC 210

D8: Advanced Iterators

Teaching

Please

Evaluation

Learning Goals

  • To apply the Iterator Design Pattern to a given problem
    • in the case where you need to design your own iterator class.

The Iterator Pattern

Iterator: Motivation

Joe

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

I want to modify a collection (e.g. remove an element) while iterating over it

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

  • Your class needs to implement Iterable<E>
  • Your class returns a home-made iterator when iterator() is called
  • Your iterator...
    • ...must implement Iterator<E>
    • ...usually has a counter/"cursor" that keeps track where it is
    • ...must implement hasNext() and next()

Your own iterator

Iterator Hierarchy

Iterable<E>

Iterator<E> iterator()

<<interface>>

Iterator<E>

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

<<interface>>

returns new MyCollectionIterator<E>()

MyCollection<E>

Iterator<E> iterator()

MyCollectionIterator<E>

Lecture Ticket 

public class ToyStore {
  Inventory inventory = new Inventory();

  public void displayInventory(){
    System.out.println("Why hello! May I interest you in...");
    for(Toy t : inventory){
      tryToSell(t);
    }
  }

  public void addToy(Toy t){ inventory.add(t); }

  public static void main(String[] args) {
    ToyStore allNaturalToys = new ToyStore();
    allNaturalToys.addToy(new Toy("blocks"));
    allNaturalToys.addToy(new Toy("sticks"));
    allNaturalToys.addToy(new Toy("rocks"));
    allNaturalToys.addToy(new Toy("wool"));
    allNaturalToys.unstock(new Toy("blocks"));
    allNaturalToys.displayInventory();
    allNaturalToys.analyzeShopping();
  }

  private void unstock(Toy toy) { inventory.moveToBacklog(toy); }
  private void analyzeShopping() { inventory.printQueryStats(); }
  private void tryToSell(Toy t){ System.out.println("lovely "+t+"?"); }

}
public class Inventory {
  private Collection<Toy> toys = new ArrayList<>();
  private Collection<Toy> backlog = new ArrayList<>();
  private ArrayList<String> log = new ArrayList<>();

  // getters
  public int getSize() { return toys.size(); }

  public void add(Toy t) {
    toys.add(t);
    log.add("New toy added: "+t);
  }

  public void remove(Toy t){
    toys.remove(t);
    log.add("Toy "+t+" removed");
  }

  public void printQueryStats(){
    for(String logEntry : log){
      System.out.println(logEntry);
    }
  }

  public void moveToBacklog(Toy toy) {
    toys.remove(toy);
    backlog.add(toy);
  }
}

Part 1 - Consider the Inventory class from the Toy system in the Advanced Iterator videos. If we wanted to change the order in which the toys were returned such that it interleaved sale items and regular items, which parts of the Inventory class (and its associated Iterator inner class) would have to change?

Part 2 - If you wanted to change the Inventory's iterator so that it iterates over objects of type String instead of Toy, what would need to change?

Lecture Lab

Advanced Iterators

Lecture Lab - Part 1

  • Carry out the change that Inventory's iterator returns Strings (names of Toys) instead of Toys themselves
    • What would need to change?
    • Perform the change and make sure you got it working!

Task 1: Toy Names instead of Toys

Lecture Lab - Part 2

  • Why don't we always just put the things we want to iterate over in a list, and then use the list's iterator?
  • Example: there is no (practical) limit on the number of items that the iterator will produce
  • Rather than producing a finite stream of values, these iterators produce an (essentially) infinite stream of values

Task 2: Odds Iterator

Lecture Lab - Part 2 (2)

Task 2: Odds Iterator

  • Make the Odds class Iterable!
    • The OddsIterator should produce all odd positive numbers in sequence (1,3,5, etc)
    • Note that you don't need to write any additional code in the Odds class, just the OddsIterator
  • When you use the Odds iterator in a for-loop, you should plan to use a break statement to get out of the loop! Otherwise it will execute for a very .... long .... time ........
  • We want to be able to run the following loop:
for (Long l : odds) {
  assertTrue(l % 2 == 1);
  if (l >= LIMIT) break;
}

D8: Advanced Iterators

ALMOST the end of the term.

More in our last class!

The End - Thank You!

Recommended Additional Reading:
https://refactoring.guru/design-patterns/iterator

And CPSC 213, and CPSC 221, and CPSC 310!

And the rest of computing!

CPSC210 - D8: Advanced Iterators

By Steven Wolfman

CPSC210 - D8: Advanced Iterators

  • 185