Ext.: http://blog.csdn.net/zq602316498/article/details/39337899
traversing a collection with iterator mode
The iterator pattern is the standard access method used to traverse the collection class. It abstracts the access logic from different types of collection classes, thus avoiding exposing the internal structure of the collection to the client.
For example, if you are not using iterator, the way to traverse an array is to use the index: for (int i=0; i<array.size (); i++) {...} ...}
While accessing a linked list (LinkedList) must also use the while loop: while ((E=e.next ())!=null) {...} e.data () ...}
Both methods the client must know in advance the internal structure of the collection, the Access code and the collection itself is tightly coupled , unable to separate the access logic from the collection class and client code, each collection corresponding to a traversal method, the client code can not be reused.
Even more frightening, if you later need to change ArrayList to LinkedList, the original client code must all be rewritten.
To solve the above problem, the Iterator pattern always uses the same logic to traverse the collection: for (Iterator it = C.iterater (); It.hasnext ();) { ... }
The secret is that the client itself does not maintain a "pointer" that iterates through the collection, and that all internal states (such as the current element's position and whether there is a next element) are maintained by iterator , and this iterator is generated by a factory method of the collection class, so it knows how to traverse the entire collection.
The client never deals directly with the collection class, it always controls the iterator, sends a "forward", "backward", "Fetch current" command to it, and can traverse the entire collection indirectly.
First look at the definition of the Java.util.Iterator interface:
Public interface Iterator {Boolean hasnext (); Object next (); void Remove (); }
Depending on the first two methods you can complete the traversal, the typical code is as follows:
for (Iterator it = C.iterator (); It.hasnext ();) {Object o = It.next ();//operation on o ...}
Each collection class may return a different iterator specific type, and the array may return Arrayiterator,set may return Setiterator,tree may return treeiterator, but they all implement the iterator interface, so , the client doesn't care what kind of Iterator it is, it just needs to get the Iterator interface, which is the power of object-oriented.
All collection classes implement the Collection interface, while Collection inherits the Iterable interface.
[Java]View PlainCopy
- /**
- * Implementing this interface allows a 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), a Itr inner class is maintained internally, which inherits the Iterator interface, and its hasnext () and Next () methods are coupled to the ArrayList implementation. When the iterator () method of the ArrayList object is called, an instance of the class Itr is returned, enabling the ability to traverse ArrayList.
[Java]View PlainCopy
- 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 do you have to implement iterable this interface? Why not implement the iterator interface directly?
Look at the collection classes in the JDK, such as the list family or set family, are implemented Iterable interface, but do not directly implement the iterator interface. It makes sense to think carefully about it.
Because the core method of the Iterator interface next () or Hasnext () is dependent on the current iteration position of the iterator. If collection implements the iterator interface directly, it is bound to cause the collection object to contain the data (pointers) of the current iteration position. When a collection is passed between different methods, the result of the next () method becomes unpredictable because the current iteration position is not pre-provisioned. Unless you add a reset () method to the iterator interface, you can reset the current iteration position. But in this case, collection can only have one current iteration position at a time . Instead, iterable returns an iterator (a new iterator ) that counts from the beginning of each call . multiple iterators are non-interfering .
Iterator and iterable differences and linkages