COMP2511
☕ 8.2 - Iterator Pattern
In this lecture
Why?
- Understand the concepts of iterators and iterables
- Understand the motivation for the Iterator Pattern
- Discuss implementation of the Iterator Pattern in different languages
How does a for loop actually work?
List<String> shoppingList = new ArrayList<String>(
Arrays.asList(new String[] {
"apple", "banana", "pineapple", "orange"
}));
for (String item : shoppingList) {
System.out.println(item);
}
Under the hood
Iterator<String> iter = shoppingList.iterator();
while (iter.hasNext()) {
String item = iter.next();
System.out.println(item);
}
- An iterator is an object that enables a programmer to traverse a container
- Allows us to access the contents of a data structure while abstracting away its underlying representation
- In Java, for loops are an abstraction of iterators
- Iterators can tell us:
- Do we have any elements left?
- What is the next element?
Iterators
Custom Iterators
Traversing a Data Structure
- Aggregate entities (Containers)
- Stacks, Queues, Lists, Trees, Graphs, Cycles
- How do we traverse an aggregate entity without exposing its underlying representation?
- Maintain abstraction and encapsulation
- Initial solution - a method in the interface
- What if we want multiple ways to traverse the container?
Abstracting the Traversal
- Seperate Containers, Iterators and Algorithms
- Allows for many possible ways of traversal
- Avoid bloating interfaces with different traversal methods
- Client (Algorithm) requests an iterator from the container
- Container needs to provide a method for creating an iterator, to show that it is iterable
Iterators vs Iterables
- An iterable is an object that can be iterated over
- All iterators are iterable, but not all iterables are iterators
- For loops only need to be given something iterable
Iterator Invalidation
- What happens when we modify something we're iterating over?
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9]
for number in numbers:
if number == 3 or number == 4:
numbers.remove(number)
print(numbers)
Design by Contract
- In many languages, part of the postconditions of iterators is that modifying the container in certain ways causes the iterator to become invalidated (the behaviour of the iterator is undefined)
- Python
- C++
Iterator Invalidation: Java
- What happens when we modify something we're iterating over?
List<Integer> numbers = new ArrayList<Integer>(
Arrays.asList(new Integer[] {1, 2, 3, 4, 5, 6, 7, 8, 9}
));
for (Integer number : numbers) {
if (number.equals(3) || number.equals(4)) {
numbers.remove(number);
}
}
System.out.println(numbers);
Iterator Invalidation: Java
- What happens when we modify something we're iterating over?
Exception in thread "main" java.util.ConcurrentModificationException
at java.base/java.util.ArrayList$Itr.checkForComodification(ArrayList.java:1043)
at java.base/java.util.ArrayList$Itr.next(ArrayList.java:997)
at dungeonmania.DungeonManiaController.main(IterExample.java:120)
Generators
- A functional way of writing iterators
- Defined via generator functions instead of classes
- Example generator
def shopping_list():
yield 'apple'
yield 'orange'
yield 'banana'
yield 'pineapple'
for item in shopping_list():
print(item)
Iterator Categories (C++)
- Output (Write-only)
- Input (Read-only)
- Forward (most iterators, standard Java iterators)
- Bidirectional (forward and backwards)
- Random Access (iterators which function as arrays)
Copy of COMP2511 22T2 - 8.2 - Iterator Pattern
By kuroson
Copy of COMP2511 22T2 - 8.2 - Iterator Pattern
- 73