Iterators
- “An iterator is an object that allows the user to acquire and use each element in a collection one at at time.”
-
Suppose you want to process each element in a linked list. What is the problem with a traditional
for
loop like the one shown below?for (int i = 0; i < list.size(); ++i) { String item = list.get(i); // do something with item }
- As we iterate through the list, we need to keep track of where we are. But, we don’t want to expose the private
Node
object to the user (because he might mess up the list). - An iterator is simply an object that wraps up these internal details and presents a “safe” interface to the user (i.e., provides a mechanism for the developer to control what the user can do to the list).
- Basic operations:
hasNext
next
remove
- In Java, all iterators should have these three operations (as dictated by the
Iterator
interface). Some data structures may choose to provide more. - Java’s “
foreach
” loop is just “syntactic sugar” for using an iterator.- When you write
for (String s : someList)
, Java is really doing this: for (Iterator i = someList.iterator(); i.hasNext();) { String s = i.next(); // your code here}
- By having a consistent
Iterator
interface, you can use the same code to iterate through any data structure.
- When you write
Linked List iterator Implementation:
- Examine source code from book.
- Note two instance variables:
current
anditeratorModCount
current
is initialized tohead
.- This is possible because the
ListIterator
class is defined inside of theLinkedList
class. Therefore, it has direct access to the private instance data. - This access for nested classes is a feature of Java and doesn’t apply to all programming languages.
- This is possible because the
- Note two instance variables:
hasNext
just checks thatcurrent != null
next
does two things- Access the data that
current
points as - Increments
current
.
- Access the data that
remove
is not implemented? Why- (Note that
remove
removes the last element returned bynext
)
- (Note that
- Notice how this iterator limits how users can interact with
current
. - Also notice that
ListIterator
is declaredprivate
. This means that users can’t even access this class directly. They can only interact with the more generalIterator
interface.- (Look at the
LinkedList
’siterator
method).
- (Look at the
More iterator uses
- Java’s
LinkedList
class is a doubly-linked list. - It implements the
remove
method (probably because this can be done inO(1)
time.) - Java’s
LinkedList
also has aListIterator
with more features.add
- In theory, you could have an
indexOf
method return aListIterator
so you could begin iterating with a specific element. - C++ uses iterators to mark the beginning and ending element of operations like
sort
.
Comodification
- Modifying a list (or other data structure) will iterating over it can really mess things up.
- Suppose you are pointing at element 6 on the list. Then remove elements 6 and 7. When you call
next
you might end up pointing at 7, even though it was removed.
- Suppose you are pointing at element 6 on the list. Then remove elements 6 and 7. When you call
- To avoid these types of problems, Java takes a fail fast approach and watches for “comodification”.
- If such an event is detected, then an exception is raised. This exception causes the program to fail as soon as the problem is detected.
- Other languages (e.g., C++) don’t watch. It’s up to the programmer to do it right. When there is a mistake, it may not become evident for many lines of code, making it difficult to find the source of the bug.
- This is the purpose of the
iteratorModCount
variable.
ArrayList iterator implementation
- An ArrayList’s iterator is just an object that wraps up the current index.