The traverser is used to traverse the Collection, the Map does not provide a traveler providing the public, but its internal defines several private travers.
Simply put, the subclass of each AbstractRatCollection has an Iterator () method, which will return a traverser of a corresponding container. The subclass of AbstractList has a listiterator () method (ArrayList, etc. also provides the Iterator () method, from the source code you can know that Listiterator () is actually from Iterator ()! Explanation in detail below.
(*) By studying the source code, the set of Sets is actually obtained from the internal Iterator from the MAP (Hashset is obtained from the HashMap.Keyset privately, and the TreeMap.Keyset privately acquired), which is estimated It is because SET and MAP have the same nature: no repeat value is allowed. This is not discussed here.
Listiterator () is implemented in the AbstractList class. There are four inline classes in the AbstractList class: ITR, ListiTR, RandomaccessSublist and Sublist. It is related to Iterator that two of ITR and ListiTR.
ITR and ListiTR are two private embedded categories, and ITR is implemented as follows:
PRIVATE CLASS ITR IMPLEMENTS ITERATOR {
/ / Define a cursor, indicate the element Index in List
INT CURSOR = 0;
// Lastret is an index of the most recently accessed element, if the element is remove (), set to -1
INT LastRet = -1;
/ **
Modcount is the number of modifications for this list (referring to changes in structure, such as size change), usually happens while we are transversible while transove (). Note that Modcount is Transient, cannot be serialized.
If you don't equal MODCOUNT, you will explain that the List structure changes in the traversal process.
* /
INT EXPECTEDMODCOUNT = MODCOUNT;
// Hasnext () implementation
Public Boolean Hasnext () {
RETURN CURSOR! = size ();
}
// NEXT () implementation
Public Object next () {
Try {
Object next = GET (CURSOR);
CheckForComodification ();
Lastret = CURSOR ;
Return NEXT;
} catch (indexoutofboundsexception e) {
CheckForComodification ();
Throw new nosuchelementexception ();
}
}
// Remove () implementation
Public void remove () {
IF (Lastret == -1)
Throw new IllegalStateException ();
CheckForComodification ();
Try {
/ **
AbstractList.remove () will throw unsupportedOperationException, if
If a subclass allows the REMOVE (int) operation, you must override this method.
* /
AbstractList.this.remove (Lastret);
IF (Lastret Cursor -; Lastret = -1; Expectedmodcount = Modcount; } catch (indexoutofboundsexception e) { Throw new concurrentmodificationException (); } } / / Check if the List is modified Final void CheckforComodification () { IF (MODCOUNT! = EXPECTEDMODCOUNT) Throw new concurrentmodificationException (); } } AbstractList.iterator () is actually only one line: Return New ITR (); returns an ITR instance. It can be seen that the method in the ITR class is called, such as Get (int), Remove (int), etc., but these methods are either abstract, or only one sentence: throw new unsupportedOperationException (); like this ABSTRACTLIST If these methods are implemented, they are useful if they inherit it. If you do not allow GET (Int), Remove (int), it will also be disabled. As shown below: ArrayList To provide a traverser, you only need to overwrite it inheriting the get (int) and remove (int) method of AbstractList. That is, the popular behavior of the traversators is defined in AbstractList, and other specific classes only need to overwrite several methods according to their own features. ListiTR embedded category inherits the ITR class, the source code is as follows: PRIVATE CLASS LISTITITR EXTENDS ITR IMPLEMENTS ListItem { ListiTR (int index) { Cursor = Index; } Public Boolean Hasprevious () { RETURN CURSOR! = 0; } Public Object previous () { Try { INT i = CURSOR - 1; Object previous = get (i); CheckForComodification (); Lastret = CURSOR = I; Return Previous; } catch (indexoutofboundsexception e) { CheckForComodification (); Throw new nosuchelementexception (); } } Public int nextIndex () { Return Cursor; } Public int readyIndex () { Return Cursor-1; } Public Void Set (Object O) { IF (Lastret == -1) Throw new IllegalStateException (); CheckForComodification (); // Check if there is a modification Try { AbstractList.This.Set (Lastret, O); Expectedmodcount = Modcount; } catch (indexoutofboundsexception e) { Throw new concurrentmodificationException (); } } Public Void Add (Object O) { CheckForComodification (); Try { AbstractList.This.Add (Cursor , O); Lastret = -1; Expectedmodcount = Modcount; } catch (indexoutofboundsexception e) { Throw new concurrentmodificationException (); } } } AbstractList.listIstItIn: (1) Public Listiterator ListIterator () { Return Listiterator (0); } (2) Public Listiterator Listiterator (Final INDEX) { IF (Index <0 || index> size ()) Throw new indexoutofboundsexception ("INDEX:" index); Return New ListiTR (INDEX); } Joshua Bloch Designed the beauty of Collection architecture, only slowly understand in the source code ...