Iterator in java

An iterator is an object that can traverse a collection of data.

The basic concept of an iterator: an iterator can be regarded as a program component, which provides users with related methods. Calling these methods
can control the iterative process.

Note: When using Iterator directly (rather than indirectly through an enhanced for loop), it is important to remember a basic rule, if you make structural changes to the collection being iterated, use clear(), add (), remove() and other methods, then the iterator is no longer legal.

The java.util package contains two standard interfaces,They are the Iterator and ListIterator interfaces.

(1) Three methods (and other methods) are explained in the Iterator interface. hasNext, next, remove,.
HasNext to check whether the iterator has the next item to return, if so, next returns a reference to it. The method remove can delete the last item returned when next is called.
If hasNxet returns true. The method next moves the cursor of the iterator to the next element and returns a reference to that element. If not, the NoSuchElementException
remove method deletes the last element returned by the iterator from the collection pointed to by the iterator. This method can only be called once for each call to the next method.
(2)
ListIterator extends the function of List Iterator. The methods previous and hasPrevious make it possible to complete the traversal of the table from back to front.
For LinkedList, add is a constant time operation, but for ArrayList it is expensive.
Set changes the last value seen by the iterator, which is very convenient for ListIterator.
Insert picture description here

java.lang.Iterable interface
Insert picture description here

The difference and connection between Iterable and Iterator.

==Use Iterator mode to traverse the collection==

Iterator mode is a standard access method for traversing collection classes. It can abstract the access logic from different types of collection classes to avoid exposing the internal structure of the collection to the client.
For example, if the Iterator is not used, the way to traverse an array is to use the index: for(int i=0; i<array.size(); i++) {… get(i)…}
and access to a linked list (LinkedList) must Use a while loop: while((e=e.next())!=null) {… e.data()…}

In the above two methods, the client must know the internal structure of the collection in advance. The access code and the collection itself are tightly coupled, and the access logic cannot be separated from the collection class and the client code. Each collection corresponds to a traversal method. End code cannot be reused.
Even more frightening is that if you need to replace ArrayList with LinkedList in the future, the original client code must be completely rewritten.
To solve the above problems, the Iterator mode always uses the same logic to traverse the collection: for(Iterator it = c.iterater(); it.hasNext();) {…}

The mystery is that the client itself does not maintain the "pointer" that traverses the collection. All internal states (such as the current element position and whether there is the next element) are maintained by Iterator, and this Iterator is generated by the collection class through a factory method. Therefore, it Know how to traverse the entire collection.

The client never directly deals with the collection class. It always controls the Iterator and sends it "forward", "backward", and "take current element" commands to indirectly traverse the entire collection.

First 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(); // Operation on o... }

The specific type of Iterator 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 what iterator is, it only You need to get this Iterator interface, which is the power of object-oriented.

All collection classes implement the Collection interface, and 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();
}

Why must we implement the Iterable interface? Why not directly implement the Iterator interface?

Take a look at the collection classes in the JDK, such as the List family or the Set family, which implement the Iterable interface, but do not directly implement the Iterator interface. It makes sense to think about it carefully because the core method next() or hasNext() of the Iterator interface depends on the current iteration position of the iterator. If Collection directly implements the Iterator interface, it will inevitably cause the collection object to contain the data (pointer) of the current iteration position. When the collection is passed between different methods, because the current iteration position cannot be preset, the result of the next() method will become unpredictable. Unless you add a reset() method to the Iterator interface to reset the current iteration position. But even in this case, the Collection can only have one current iteration position at the same time. The Iterable is not the case, each call will return an iterator counting from the beginning. Multiple iterators do not interfere with each other.

Use of multiple iterators

List<String> nameList = new ArrayList<>();
        nameList.add("banana");
        nameList.add("cherry");
        nameList.add("apple");
        nameList.add("cherry");
        nameList.add("banana");
        Iterator<String> nameIterator = nameList.iterator();
        while (nameIterator.hasNext()){
    
    
            String currentName = nameIterator.next();
            int nameCount = 0;
            Iterator<String> countingIterator = nameList.iterator();
            while (countingIterator.hasNext()){
    
    
                String nextName = countingIterator.next();
                if (currentName.equals(nextName))
                    nameCount++;
            }
            System.out.println(currentName+"occurs"+nameCount+"times");
        }

Guess you like

Origin blog.csdn.net/weixin_45773632/article/details/109559967