design pattern #2: iterator · cisc 323, winter 2003, design patterns 1 design pattern #2: iterator...

33
CISC 323, Winter 2003, Design Patterns 1 Design Pattern #2: Iterator There are many kinds of data structures for storing a collection of data. Common need: take some action with each element of the collection Example: list of numbers add up all the numbers look for a particular number check to see if any number is outside the legal range check to see if the collection is in numerical order Common feature of all these operations: need to walk through collection in order, doing something with each element. Called iterating over a collection.

Upload: others

Post on 15-Jul-2020

3 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Design Pattern #2: Iterator · CISC 323, Winter 2003, Design Patterns 1 Design Pattern #2: Iterator There are many kinds of data structures for storing a collection of data. Common

CISC 323, Winter 2003, Design Patterns 1

Design Pattern #2: Iterator

There are many kinds of data structures for storing a collection of data.

Common need: take some action with each element of the collection

Example: list of numbers• add up all the numbers• look for a particular number• check to see if any number is outside the legal range• check to see if the collection is in numerical order

Common feature of all these operations: need to walk through collection in order, doing something with each element. Called iterating over a collection.

Page 2: Design Pattern #2: Iterator · CISC 323, Winter 2003, Design Patterns 1 Design Pattern #2: Iterator There are many kinds of data structures for storing a collection of data. Common

CISC 323, Winter 2003, Design Patterns 2

Recall CourseList Interface

"first" and "rest" from previous example omitted for simplicity

<<interface>>CourseList

numElements(): intinList(Course c): boolean remove(Course c)add(Course c)get(int n): Course

Course*

Page 3: Design Pattern #2: Iterator · CISC 323, Winter 2003, Design Patterns 1 Design Pattern #2: Iterator There are many kinds of data structures for storing a collection of data. Common

CISC 323, Winter 2003, Design Patterns 3

Implementations of CourseList

Many possible implementations including:• array• Vector• linked list• tree (BST, AVL, 2,4 tree, etc.)• hash table

Whichever we choose, details should be invisible to user

Might want to provide multiple implementations with different performance characteristics:• times for each operation (add, remove, get)• space versus time• are Courses kept in some kind of order?

Page 4: Design Pattern #2: Iterator · CISC 323, Winter 2003, Design Patterns 1 Design Pattern #2: Iterator There are many kinds of data structures for storing a collection of data. Common

CISC 323, Winter 2003, Design Patterns 4

Iterating Over a CourseList

Why would we need to iterate over a course list?• print a list of all the courses• look for courses that match some criteria

CISC coursesgraduate coursesetc.

• add up total enrollment• create a schedule• allocate rooms for each course• etc.

Page 5: Design Pattern #2: Iterator · CISC 323, Winter 2003, Design Patterns 1 Design Pattern #2: Iterator There are many kinds of data structures for storing a collection of data. Common

CISC 323, Winter 2003, Design Patterns 5

How To Iterate

The CourseList interface gives us a get method, which we could use to iterate over the list:

for (int i = 0; i < clist.numElements; i++) {Course c = clist.get(i);... do something with c

}

Problem: Very inefficient for many implementations.

Page 6: Design Pattern #2: Iterator · CISC 323, Winter 2003, Design Patterns 1 Design Pattern #2: Iterator There are many kinds of data structures for storing a collection of data. Common

CISC 323, Winter 2003, Design Patterns 6

Linked List Implementation

course 1head course 2 course 3 ....

to get element n:• start at head of list• advance n times• slow if list is long and n is large

so iteration using get method is inefficient

Page 7: Design Pattern #2: Iterator · CISC 323, Winter 2003, Design Patterns 1 Design Pattern #2: Iterator There are many kinds of data structures for storing a collection of data. Common

CISC 323, Winter 2003, Design Patterns 7

Better Way For Linked Lists

for (LinkedNode node = head; node != null; node = ptr.next) {...do something with node.course...

}

course 1head course 2 course 3 ....

Problem: user needs access to internal data

Page 8: Design Pattern #2: Iterator · CISC 323, Winter 2003, Design Patterns 1 Design Pattern #2: Iterator There are many kinds of data structures for storing a collection of data. Common

CISC 323, Winter 2003, Design Patterns 8

General Question

How can we provide an efficient, convenient way for the user to iterate over a collection while still hiding implementation details?• user doesn't have to take the time to learn about data

structure being used• don't give user permission to mess with internal data

Answer: create a separate object to control iteration

Called an Iterator

Another advantage: write logic for iterating once only, not for each loop.

Page 9: Design Pattern #2: Iterator · CISC 323, Winter 2003, Design Patterns 1 Design Pattern #2: Iterator There are many kinds of data structures for storing a collection of data. Common

CISC 323, Winter 2003, Design Patterns 9

Common Elements of Iteration

What does an Iterator object have to do?1. begin an iteration (i.e. start with the first element)2. tell user if we're finished (i.e. are there more elements?)3. get the current element4. advance to the next element

Page 10: Design Pattern #2: Iterator · CISC 323, Winter 2003, Design Patterns 1 Design Pattern #2: Iterator There are many kinds of data structures for storing a collection of data. Common

CISC 323, Winter 2003, Design Patterns 10

Iterating Over a Linked List

for (LinkedNode node = head; node != null; node = ptr.next) {...do something with node.course...

}

begin the iteration

Page 11: Design Pattern #2: Iterator · CISC 323, Winter 2003, Design Patterns 1 Design Pattern #2: Iterator There are many kinds of data structures for storing a collection of data. Common

CISC 323, Winter 2003, Design Patterns 11

Iterating Over a Linked List

for (LinkedNode node = head; node != null; node = ptr.next) {...do something with node.course...

}

are we done yet?

Page 12: Design Pattern #2: Iterator · CISC 323, Winter 2003, Design Patterns 1 Design Pattern #2: Iterator There are many kinds of data structures for storing a collection of data. Common

CISC 323, Winter 2003, Design Patterns 12

Iterating Over a Linked List

for (LinkedNode node = head; node != null; node = ptr.next) {...do something with node.course...

} access the current element

Page 13: Design Pattern #2: Iterator · CISC 323, Winter 2003, Design Patterns 1 Design Pattern #2: Iterator There are many kinds of data structures for storing a collection of data. Common

CISC 323, Winter 2003, Design Patterns 13

Iterating Over a Linked List

for (LinkedNode node = head; node != null; node = ptr.next) {...do something with node.course...

}

advance to next element

Page 14: Design Pattern #2: Iterator · CISC 323, Winter 2003, Design Patterns 1 Design Pattern #2: Iterator There are many kinds of data structures for storing a collection of data. Common

CISC 323, Winter 2003, Design Patterns 14

Iterating Over an Array

for (int i = 0; i < size; i++) {...do something with courses[i]...

}

begin the iteration

Page 15: Design Pattern #2: Iterator · CISC 323, Winter 2003, Design Patterns 1 Design Pattern #2: Iterator There are many kinds of data structures for storing a collection of data. Common

CISC 323, Winter 2003, Design Patterns 15

Iterating Over an Array

for (int i = 0; i < size; i++) {...do something with courses[i]...

}

are we done yet?

Page 16: Design Pattern #2: Iterator · CISC 323, Winter 2003, Design Patterns 1 Design Pattern #2: Iterator There are many kinds of data structures for storing a collection of data. Common

CISC 323, Winter 2003, Design Patterns 16

Iterating Over an Array

for (int i = 0; i < size; i++) {...do something with courses[i]...

} access the current element

Page 17: Design Pattern #2: Iterator · CISC 323, Winter 2003, Design Patterns 1 Design Pattern #2: Iterator There are many kinds of data structures for storing a collection of data. Common

CISC 323, Winter 2003, Design Patterns 17

Iterating Over an Array

for (int i = 0; i < size; i++) {...do something with courses[i]...

}

advance to next element

Page 18: Design Pattern #2: Iterator · CISC 323, Winter 2003, Design Patterns 1 Design Pattern #2: Iterator There are many kinds of data structures for storing a collection of data. Common

CISC 323, Winter 2003, Design Patterns 18

A CourseList Iterator<<interface>>CourseList

numElements(): intinList(Course c): boolean remove(Course c)add(Course c)get(int n): CoursecreateIterator(): CourseListIterator

Course*

<<interface>>CourseListIterator

first(): Coursenext(): CourseIsDone(): booleanCurrentItem(): Course

createsiterates over

Think of an iterator as an object that "points to" an element in the list.

Page 19: Design Pattern #2: Iterator · CISC 323, Winter 2003, Design Patterns 1 Design Pattern #2: Iterator There are many kinds of data structures for storing a collection of data. Common

CISC 323, Winter 2003, Design Patterns 19

Using an IteratorCourseList myList = ....;....CourseListIterator iter = myList.createIterator();while (!iter.IsDone()) {

Course thisCourse = iter.currentItem();... do something with thisCourse ...iter.next(); // move to next item

} // end while

// to start a new iteration:iter.first(); // resets to the beginning of the list

Page 20: Design Pattern #2: Iterator · CISC 323, Winter 2003, Design Patterns 1 Design Pattern #2: Iterator There are many kinds of data structures for storing a collection of data. Common

CISC 323, Winter 2003, Design Patterns 20

Java Class: Enumeration

Previous example used Design Patterns terminology for Iterator methods.Java API includes Enumeration interface (in java.util)• provides the same functionality• different method names

When writing in Java, nice to use Enumeration since it's familiar to Java programmers.

public interface Enumeration {public boolean hasMoreElements();public Object nextElement();

}

Page 21: Design Pattern #2: Iterator · CISC 323, Winter 2003, Design Patterns 1 Design Pattern #2: Iterator There are many kinds of data structures for storing a collection of data. Common

CISC 323, Winter 2003, Design Patterns 21

Enumeration Methodspublic boolean hasMoreElements():

• returns true if there are more elements to look at• exactly like !isDone()public Object nextElement();

• returns current element and advances to next• combines currentItem and next• so:

Course thisCourse = (Course)enum.nextElement();

• is equivalent to:Course thisCourse = iter.currentItem();iter.next(); // move to next item

There is no method to start the enumeration over at the beginning like first(). To do that, create a new enumeration.

Page 22: Design Pattern #2: Iterator · CISC 323, Winter 2003, Design Patterns 1 Design Pattern #2: Iterator There are many kinds of data structures for storing a collection of data. Common

CISC 323, Winter 2003, Design Patterns 22

Implementing Enumeration for Course Lists

We will need an implementation of Enumeration for each implementation of CourseList

Page 23: Design Pattern #2: Iterator · CISC 323, Winter 2003, Design Patterns 1 Design Pattern #2: Iterator There are many kinds of data structures for storing a collection of data. Common

CISC 323, Winter 2003, Design Patterns 23

Using Inner Classes

The Enumeration needs access to the internal data structures of the course listWe don't want to give all user's such accessSolution: implement Enumerations as inner classes• ArrayEnum is inner class of CourseArrayList• LinkedEnum is inner class of CourseLinkedList

User doesn't have to keep track of these inner classesUser calls enumeration() method and is given the appropriate kind of Enumeration objectExample of a "factory method": a method that creates an object and takes care of deciding what particular kind of object

Page 24: Design Pattern #2: Iterator · CISC 323, Winter 2003, Design Patterns 1 Design Pattern #2: Iterator There are many kinds of data structures for storing a collection of data. Common

CISC 323, Winter 2003, Design Patterns 24

Linked List Implementation (1)public class CourseLinkedList implements CourseList {private class ListNode {Course course;ListNode next;

}private ListNode head = null;

// get, remove, etc.

Page 25: Design Pattern #2: Iterator · CISC 323, Winter 2003, Design Patterns 1 Design Pattern #2: Iterator There are many kinds of data structures for storing a collection of data. Common

CISC 323, Winter 2003, Design Patterns 25

Linked List Implementation (2)public class CourseLinkedList implements CourseList {private class ListNode {Course course;ListNode next;

}private ListNode head = null;

// get, remove, etc.

private class LinkedEnum implements Enumeration {...

} // end inner class LinkedEnum

Page 26: Design Pattern #2: Iterator · CISC 323, Winter 2003, Design Patterns 1 Design Pattern #2: Iterator There are many kinds of data structures for storing a collection of data. Common

CISC 323, Winter 2003, Design Patterns 26

Linked List Implementation (3)public class CourseLinkedList implements CourseList {private class ListNode {Course course;ListNode next;

}private ListNode head = null;

// get, remove, etc.

private class LinkedEnum implements Enumeration {...

} // end inner class LinkedEnum

public Enumeration enumeration() { return new LinkedEnum();

} // end enumeration

} // end class CourseLinkedList

Page 27: Design Pattern #2: Iterator · CISC 323, Winter 2003, Design Patterns 1 Design Pattern #2: Iterator There are many kinds of data structures for storing a collection of data. Common

CISC 323, Winter 2003, Design Patterns 27

Details of Inner Classprivate class LinkedEnum implements Enumeration {ListNode nextNode = head; // next element to return

public boolean hasMoreElements() {return nextNode != null;

}

// Java convention: throw an exception if you've already// gone through all the elementspublic Object nextElement() throws NoSuchElementException {if (!hasMoreElements()) {throw new NoSuchElementException();

}else {Course returnVal = nextNode.course;nextNode = nextNode.next;return returnVal;

} // end if} // end nextElement

} // end inner class LinkedEnum

Page 28: Design Pattern #2: Iterator · CISC 323, Winter 2003, Design Patterns 1 Design Pattern #2: Iterator There are many kinds of data structures for storing a collection of data. Common

CISC 323, Winter 2003, Design Patterns 28

Array Implementation

Contains inner class: ArrayEnumInstead of node pointer, inner class contains index of next elementfull code for example is on the web page (link near the slides)

Page 29: Design Pattern #2: Iterator · CISC 323, Winter 2003, Design Patterns 1 Design Pattern #2: Iterator There are many kinds of data structures for storing a collection of data. Common

CISC 323, Winter 2003, Design Patterns 29

Using a CourseList EnumerationCourseList myList = new CourseArrayList();... add elements to myList

// a loop to print all courses in listEnumeration listEnum = myList.enumeration();while (listEnum.hasMoreElements()) {

Course c = (Course) listEnum.nextElement();System.out.print(c + " ");

} // end whileSystem.out.println();

To use the linked list implementation instead:CourseList myList = new CourseLinkedList();

No other changes necessary.Iterating over the list is independent of implementation.

Page 30: Design Pattern #2: Iterator · CISC 323, Winter 2003, Design Patterns 1 Design Pattern #2: Iterator There are many kinds of data structures for storing a collection of data. Common

CISC 323, Winter 2003, Design Patterns 30

General Iterator Design Pattern

Page 31: Design Pattern #2: Iterator · CISC 323, Winter 2003, Design Patterns 1 Design Pattern #2: Iterator There are many kinds of data structures for storing a collection of data. Common

CISC 323, Winter 2003, Design Patterns 31

Danger: Changing the Collection

What happens if you change the underlying collection during an iteration?Example:CourseList myList = new CourseArrayList();myList.add(new Course("CISC 121"));myList.add(new Course("ELEC 276"));myList.add(new Course("CISC 323"));Enumeration enum = myList.enumeration();Course course1 = (Course) enum.nextElement();Course course2 = (Course) enum.nextElement();myList.remove(course1);Course course3 = (Course) enum.nextElement();

Throws an exception. The enumeration was storing an index into the array of courses. When we removed an earlier course, the index became invalid.

Page 32: Design Pattern #2: Iterator · CISC 323, Winter 2003, Design Patterns 1 Design Pattern #2: Iterator There are many kinds of data structures for storing a collection of data. Common

CISC 323, Winter 2003, Design Patterns 32

Robust Iterators

A "robust iterator" is an iterator that doesn't fail even if you add to or remove from the underlying collection.Robust iterators are hard to writeMost iterators are not robust

Page 33: Design Pattern #2: Iterator · CISC 323, Winter 2003, Design Patterns 1 Design Pattern #2: Iterator There are many kinds of data structures for storing a collection of data. Common

CISC 323, Winter 2003, Design Patterns 33

The Java Iterator Class

The Enumeration class came with Java 1.0Version 1.2 & later include a new class: Iteratorrenames the two methods from Enumerationcontains an additional method for removing an element from the underlying collection: allows filtering a collection

Reasons we've taught you Enumeration class instead:• still used and included in Java API• remove method is not part of Iterator design pattern• code you will use for Assignment 3 includes Enumerations