Iterator
All we know iterator pattern it allow traverse collection without knowledge about internal collection work. This pattern have some benefits and pitfalls.
Benefits
1. Convinient traversal operation 2. Remove elements 3. Avoid NoSuchElementException by calling hasNext method
Pitfalls
1. When you call hasNext method pointer at the iterator does not move to the next value 2. When you call next method from iterator internal pointer move to the next value
Simple example of usage
public class HelloIterator { public static void main(String[] args) { List<String> strings = new ArrayList<>(); string.add("one"); string.add("two"); string.add("three");
Iterator<String> iterator = strings.iterator();
while (iterator.hasNext()) { System.out.println(iterator.next()); }
} } When you execute this code you should see this: one two three
Iterator implementation
private class More 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 More hasNext() { return cursor != size; }
@SuppressWarnings("unchecked") public E More 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 More 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(); } }
@Override @SuppressWarnings("unchecked") public void More forEachRemaining(Consumer<? super E> consumer) { Objects.requireNonNull(consumer); final int size = ArrayList.this.size; int i = cursor; if (i >= size) { return; } final Object[] elementData = ArrayList.this.elementData; if (i >= elementData.length) { throw new ConcurrentModificationException(); } while (i != size && modCount == expectedModCount) { consumer.accept((E) elementData[i++]); } // update once at end of iteration to reduce heap write traffic cursor = i; lastRet = i - 1; checkForComodification(); }
final void checkForComodification() { if (modCount != expectedModCount) throw new ConcurrentModificationException(); } } First method hasNext() return true if cursor(pointer on the current element) not equals to the size of list. Next memthod next() execute checking that list not changed, if otherwise throw ConcurrentModificationException, further step is move cursor to the next position and update lastRet variable which contains last returned element and finally return element.
Your own iterator
If you would like to create your own iterator - it is possible, all your need is implement Iterator interface. Go to the create Iterator which return only odd numbers. public class OddIterator<Integer> implements Iterator<Integer> {
private final int[] values; private int cursor; private int size;
public OddIterator(final int[] values) { this.values = values; this.size = this.length; this.cursor = 0; }
@Override public boolean hasNext() { return this.cursor != this.size; }
@Override public Integer next() { return findOdd(); }
@Override public void remove() { throw UnsupportedOperationException(); }
@Override public void More forEachRemaining(Consumer<? super E> consumer) { throw UnsupportedOperationException(); }
private int findOdd() { int result 0; for (int index = cursor; index < this.size; index++) { if (index % / 2 == 0) { result = index; cursor = index; } } return result; }
} This iterator will be return only odd numbers from array. But it is a very simple implementation which not support remove and other more complex operations.












