Traverse a set in iterator Mode
The iterator mode is a standard access method used to traverse collection classes. It canThe access logic is abstracted from collection classes of the same type to avoid exposing the internal structure of the set to the client.
For example, if you do not use iterator, you can use the index to traverse an array: For (INT I = 0; I <array. size (); I ++ ){... get (I )...}
To access a linked list, you must use the while loop: While (E = E. Next ())! = NULL) {... e. Data ()...}
The client must know the internal structure of the set in advance. The access code and set itself areTight couplingThe access logic cannot be separated from the Collection class and client code. Each set corresponds to a Traversal method, and the client code cannot be reused.
What's even more frightening is that if you need to replace arraylist with a future list, all the original client code must be rewritten.
To solve the above problem, the iterator mode always uses the same logic to traverse the set: For (iterator it = C. iterater (); it. hasnext ();){...}
The mystery is that the client does not maintain the "Pointer" of the traversal set, and all internal states (such as the current element location and whether there is any next element) are maintained by iterator.The iterator is generated by the collection class through the factory method, so it knows how to traverse the entire set.
The client never directly deals with the collection class. It always controls the iterator and sends the "forward", "backward", "Get current element" command to it to indirectly traverse the entire set.
First, let's take a look at the definition of the Java. util. iterator interface:
Public interface iterator {Boolean hasnext (); object next (); void remove ();}
The traversal can be completed by relying on the first two methods. The typical code is as follows:
For (iterator it = C. iterator (); it. hasnext ();) {object o = it. Next (); // operations on o ...}
The iterator types returned by each collection class may be different. array may return arrayiterator, set may return setiterator, and tree may return treeiterator, but they all implement the iterator interface. Therefore, the client does not care about which iterator it is. It only needs to obtain this iterator interface, which is the power of object-oriented.
All collection classes implement the collection interface, while collection inherits the iterable interface.
/** * Implementing this interface allows an object to be the target of * the "foreach" statement. * * @param <T> the type of elements returned by the iterator * * @since 1.5 */public interface Iterable<T> { /** * Returns an iterator over a set of elements of type T. * * @return an Iterator. */ Iterator<T> iterator();}
In a specific implementation class (such as arraylist), an itr internal class is maintained internally, which inherits the iterator interface, its hasnext () and next () the method is coupled with the implementation of arraylist. When the iterator () method of the arraylist object is called, an itr instance of this class is returned to traverse the arraylist function.
public Iterator<E> iterator() { return new Itr(); } /** * An optimized version of AbstractList.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(); } }
Why must I implement the iterable interface? Why not directly implement the iterator interface?
Let's take a look at the collection classes in JDK. For example, the list or set classes all implement the iterable interface, but they do not directly implement the iterator interface. It makes sense to think about this.
Because the core method next () or hasnext () of the iterator interface isDependent on the current iteration position of the iterator. If the collection directly implements the iterator interface, the collection object will inevitably contain the data (pointer) at the current iteration position ). When a set is transmitted between different methods, the result of the next () method becomes unpredictable because the current iteration position cannot be preset. Unless you add a reset () method to the iterator interface to reset the current iteration position. But in real time, collection can onlyA current iteration location exists simultaneously.. Iterable does not. Each call will return an iterator counted from the beginning. Multiple iterators do not interfere with each other.
Differences and connections between iterator and iterable