We often use the iterative interface provided by JDK to iterate Java collections.
Iterator iterator = list.iterator(); while(iterator.hasNext()){String string = iterator.next();//do something} Iteration can actually be simply understood as traversal. It is a method class that standardizes traversal of all objects in various containers. It is a very typical design pattern. The Iterator pattern is a standard access method used to traverse collection classes. It abstracts access logic from different types of collection classes, thus avoiding exposing the internal structure of the collection to the client. This is how we deal with it when there is no iterator. as follows:
For arrays we use subscripts to process:
int[] arrays = new int[10];for(int i = 0 ; i < arrays.length ; i++){int a = arrays[i];//do something} This is how ArrayList is handled:
List<String> list = new ArrayList<String>(); for(int i = 0 ; i < list.size() ; i++){String string = list.get(i);//do something} For both methods, we always know in advance the internal structure of the collection. The access code and the collection themselves are tightly coupled and cannot separate the access logic from the collection class and client code. At the same time, each collection corresponds to a traversal method, and the client code cannot be reused. In practical applications, it is quite troublesome to integrate the two sets above. So in order to solve the above problems, the Iterator mode is vacant, and it always uses the same logic to traverse the collection. This makes the client itself unnecessary to maintain the internal structure of the collection, and all internal states are maintained by Iterator. The client never deals with the collection class directly. It always controls the Iterator and sends it "forward", "backward", and "take the current element" commands to it, and it can indirectly traverse the entire collection.
The above is just a brief explanation of the Iterator pattern. Let’s take a look at the Iterator interface in Java to see how it implements it.
1. java.util.Iterator
In Java, Iterator is an interface, which only provides iterative basic rules. In JDK, it is defined as this: an iterator that iterates on collection. The iterator replaces Enumeration in the Java Collections Framework. There are two differences between iterators and enumerations:
1. The iterator allows the caller to remove elements from the collection pointed to by the iterator during iteration using well-defined semantics.
2. Method name has been improved.
The interface definition is as follows:
public interface Iterator { boolean hasNext(); Object next(); void remove();} in:
Object next(): Returns the reference to the element that the iterator just crosses. The return value is Object, which needs to be cast to the type you need.
boolean hasNext(): determines whether there are any elements available in the container to access
void remove(): Remove the element that the iterator just crossed
For us, we only need to use next() and hasNext() to complete the iteration. as follows:
for(Iterator it = c.iterator(); it.hasNext(); ) { Object o = it.next(); //do something} The previous explanation is that iterator has a great advantage, that is, we do not need to know the internal results of the set. The internal structure and state of the set are maintained by Iterator. We judge and obtain the next element through the unified methods hasNext() and next(). As for the specific internal implementation, we don't need to worry about it. But as a qualified programmer, it is very necessary to figure out the implementation of Iterator. The source code of ArrayList is analyzed below.
2. Implementation of Iterator for each collection
Let’s analyze the Iterator implementation of ArrayList. In fact, if we understand the data structures of ArrayList, Hashset, and TreeSet and implement them internally, we will be confident about how they implement Iterator. Because the internal implementation of ArrayList uses an array, we only need to record the index of the corresponding position, and the implementation of its method is relatively simple.
2.1. Iterator implementation of ArrayList
Inside ArrayList, first defines an inner class Itr, which implements the Iterator interface, as follows:
private class Itr implements Iterator<E> {//do something} And the iterator() method of ArrayList is implemented:
public Iterator<E> iterator() {return new Itr();} So the method of ArrayList.iterator() returns the Itr() inner class, so what we need to care about now is the implementation of the Itr() inner class:
Three int-type variables are defined inside Itr: cursor, lastRet, and expectedModCount. where cursor represents the index position of the next element, and lastRet represents the index position of the previous element
int cursor; int lastRet = -1; int expectedModCount = modCount;
From the definitions of cursor and lastRet, it can be seen that lastRet has always been one less than cursor, so the implementation method of hasNext() is extremely simple. You only need to judge whether cursor and lastRet are equal.
public boolean hasNext() {return cursor != size;} The implementation of next() is actually relatively simple. Just return the element at the cursor index position, and then modify the cursor and lastRet
public E next() {checkForComodification();int i = cursor; //Record index position if (i >= size) //If the obtain element is greater than the number of set elements, an exception is thrown throw new NoSuchElementException();Object[] elementData = ArrayList.this.elementData; if (i >= elementData.length)throw new ConcurrentModificationException();cursor = i + 1; //cursor + 1return (E) elementData[lastRet = i]; //lastRet + 1 and return the element at cursor} checkForComodification() is mainly used to determine whether the number of modifications of a set is legal, that is, to determine whether the set has been modified during the traversal process. modCount is used to record the number of modifications of the ArrayList collection, initialized to 0, and whenever the collection is modified once (the internal update does not count for the structure), such as add, remove and other methods, modCount + 1, so if modCount remains unchanged, it means that the content of the collection has not been modified. This mechanism is mainly used to implement the fast failure mechanism of ArrayList collection. In Java collections, a large part of the collections have a fast failure mechanism. I won't talk about it here, and I will talk about it later. Therefore, to ensure that there are no errors during the traversal process, we should ensure that there will be no structural modifications to the collection during the traversal process (except for the remove method). If an exception error occurs, we should carefully check whether the program has an error instead of not processing it after catch.
final void checkForComodification() {if (modCount != expectedModCount)throw new ConcurrentModificationException();} The remove() method is an implementation, which calls the remove() method of ArrayList itself to delete the lastRet position element, and then modify modCount.
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();}}The above is the implementation method of Java collection Iterator iteration introduced to you by the editor. I hope it will be helpful to you. If you have any questions, please leave me a message and the editor will reply to you in time. Thank you very much for your support to Wulin.com website!