Iterator mode: Provides a way to access elements in a collection object sequentially without exposing their internal representations.
class diagram
Aggregate: Aggregate is a container that provides an abstract createIterator() method to return iterators.
ConcreteAggregate: Specific container classes, such as the commonly used ArrayList, HashMap, and so on, implement the createIterator() method specifically.
Iterator: The interface that all iterators must implement.Traverse through collection elements using methods provided internally.
ConcreteIterator: Specific iterator implementation.Iterators such as those returned by ArrayList and those returned by the HashMap keySet() method.
Take a look at the iterators returned by ArrayList
In Java, you can iterate through an ArrayList using an iterator.(Ordinarily a direct for loop).
ArrayList<String> list = new ArrayList<>();
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
In Java, HashMap can be traversed through an iterator.
HashMap<String, String> hashMap = new HashMap<>();
Iterator<String> iterator1 = hashMap.keySet().iterator();
while (iterator1.hasNext()) {
String key = iterator1.next();
System.out.println("key:" + key + ",value:" + hashMap.get(key));
}
In Java, collections inherit from Collection, and Collection inherits the Iterable interface, which defines the iterator() method.
public interface Iterable<T> {
Iterator<T> iterator();
}
The iterator() method returns an Iterator.
public interface Iterator<E> {
boolean hasNext();
E next();
default void remove() {
throw new UnsupportedOperationException("remove");
}
//...Omit other methods
Different specific collections have different implementations of the Iterator<E>interface.
Implementation of ArrayList.
public Iterator<E> iterator() {
return new Itr();
}
private class Itr implements Iterator<E> {
int cursor; // index of next element to return
int lastRet = -1; // index of last element returned; -1 if no such
int expectedModCount = modCount;
public boolean hasNext() {
return cursor != size;
}
@SuppressWarnings("unchecked")
public E next() {
checkForComodification();
int i = cursor;
if (i >= size)
throw new NoSuchElementException();
Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length)
throw new ConcurrentModificationException();
cursor = i + 1;
return (E) elementData[lastRet = i];
}
public void remove() {
if (lastRet < 0)
throw new IllegalStateException();
checkForComodification();
try {
ArrayList.this.remove(lastRet);
cursor = lastRet;
lastRet = -1;
expectedModCount = modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
}
HashMap is traversed using Set.
public Set<K> keySet() {
Set<K> ks;
return (ks = keySet) == null ? (keySet = new KeySet()) : ks;
}
//KetSet class
final class KeySet extends AbstractSet<K> {
public final Iterator<K> iterator(){
return new KeyIterator();
}
//Omit other methods
}
//KeyIterator class
final class KeyIterator extends HashIterator
implements Iterator<K> {
public final K next() { return nextNode().key; }
}
//HashIterator class
abstract class HashIterator {
Node<K,V> next; // next entry to return
Node<K,V> current; // current entry
int expectedModCount; // for fast-fail
int index; // current slot
HashIterator() {
expectedModCount = modCount;
Node<K,V>[] t = table;
current = next = null;
index = 0;
if (t != null && size > 0) { // advance to first entry
do {} while (index < t.length && (next = t[index++]) == null);
}
}
public final boolean hasNext() {
return next != null;
}
final Node<K,V> nextNode() {
Node<K,V>[] t;
Node<K,V> e = next;
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
if (e == null)
throw new NoSuchElementException();
if ((next = (current = e).next) == null && (t = table) != null) {
do {} while (index < t.length && (next = t[index++]) == null);
}
return e;
}
public final void remove() {
Node<K,V> p = current;
if (p == null)
throw new IllegalStateException();
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
current = null;
K key = p.key;
removeNode(hash(key), key, null, false, false);
expectedModCount = modCount;
}
}
The code above shows how each iterator is implemented inside ArrayList and HashMap, but when we use iterators, we don't care how the details inside them are implemented at all.All we need to know is that iterators can iterate through the set.
Finally, let's look at the definition of the iterator pattern, is it much clearer?
Iterator mode: Provides a way to access elements in a collection object sequentially without exposing their internal representations.
End: Reference
[1] Head First design mode.