Daily class 1 - handwritten ArrayList iterator

Keywords: Java Design Pattern arraylist iterator

summary

        Continue with the previous chapter: Daily class - handwritten ArrayList - Generic , this article will talk about the implementation details of the iterator of ArrayList. Due to space constraints, this article first implements the one-way iterative method iterator(), and the two-way iterative listIterator() will be implemented in the next article.

Iterator mode

        Talking about iterator()   Before ListIterator(), let's popularize the iterator pattern.    

         Baidu Encyclopedia gives an introduction: Iterator mode provides a method to sequentially access various elements in an aggregate object (set / array) without exposing the internal representation of the object.

Class diagram

Participation role

Iterator: iterator interface, which defines iterator operation rules. Generally, there are three core methods,

    1> Hasnext() determines whether it can be iterated   2> Next () performs an iteration and returns the current element   3> Remove() deletes the iteration to the element

ConcreteIterator: iterator interface implementation class, which implements three methods of interface iteration.

Aggregate: Abstract aggregate object, a collection object that holds data. Iterators traverse the providers of elements, either abstract classes or interfaces. For example: List interface or   AbstractList abstract class.

ConcreteAggregate: the implementation of the abstract aggregate object interface (abstract class), which calls the iterator to traverse the elements one by one.

Take JDK as an example:

Iterator iterator

To implement the iterator() method, the above iterator pattern structure should be established:

MyIterator

/**
 * Iterator interface: defining iteration rules
 */
public interface MyIterator<E> {
    /**
     * Judge whether there is a next element (judge whether it can be iterated)
     * @return
     */
    boolean hasNext();

    /**
     * Get current iteration to element (execute next iteration element)
     * @return
     */
    E next();

    /**
     * Deletes the element to which the current iteration is applied
     */
    void remove();
}

The MyIterator interface defines the rules of iterators. There are at least three core methods of iterators: hasNext, next and remove.

Operation diagram

  When next() is executed, cursor will automatically move down

Note: there is another way to understand:

The cursor is located in front of the first element. Each time you move it, you skip one element. Personally, I think there is no difference in operation.  

MyItr 

It is defined inside the MyArrayList class and is not exposed

public class MyArrayList<E> {
   /**
     * MyArrayList Class internal definition private internal class MyItr
     * Objective: to implement the iterator corresponding to hidden MyArrayList
     *  MyArrayList The iterative interface can be exposed mainly through the iterator method.
     */
    private class MyItr implements MyIterator<E>{
        //Cursor (index) starts at 0
        private int cursor;
        @Override
        public boolean hasNext() {
            //As long as you don't iterate to the end, you can iterate all the time
            return cursor != size;
        }
        @Override
        public E next() {
            //During iteration, if the cursor exceeds the total number, an error is reported
            if (cursor >= size)
                throw new NoSuchElementException();
            //++Indicates that next is the next element
            return (E) elementData[cursor++];
        }
        @Override
        public void remove() {
            //In the above, if the remove operation is called immediately without executing next first, it will prompt illegal operation
            if (cursor < 1){
                throw new IllegalStateException("Please execute first next method");
            }
            //The cursor is still within the operational range
            if(cursor <= size){
                //After the next method, the cursor executes with the next element. If you want to delete, delete the current element
                //The cursor returns to the previous value
                MyArrayList.this.remove(cursor -1);
                //After deletion, the size-1 in the collection and the right should also be synchronized with - 1
                cursor--;
            }
        }
    }

}

  Define the iterator method in the MyArrayList class and provide the operation object of the iterator for iteration

public class MyArrayList<E> {
    .....
    /**
     * Expose iterator methods for manipulating collection iterators
     * Note that interface polymorphism is used here to effectively hide the implementation details of MyItr private inner class
     * @return
     */
    public MyIterator<E> iterator(){
        return new MyItr();
    }

    ....
}

Iterative testing

public class App{
    public static void main(String[] args) {
        MyArrayList<String> list = new MyArrayList<>();
        list.add("a");
        list.add("b");
        list.add("c");
        list.add("d");
        MyIterator<String> iterator = list.iterator();

        while (iterator.hasNext()){
            System.out.println(list);
            iterator.next();
            iterator.remove();
            System.out.println(list);
        }
    }
}

To print well, override the toString method

    public String toString() {
        MyIterator<E> it = iterator();
        if (! it.hasNext()){
            return "[]";
        }
        StringBuilder sb = new StringBuilder();
        sb.append('[');
        for (;;) {
            E e = it.next();
            sb.append(e);
            if (! it.hasNext()){
                return sb.append(']').toString();
            }
            sb.append(',').append(' ');
        }
    }
[a, b, c, d]
[b, c, d]
[b, c, d]
[c, d]
[c, d]
[d]
[d]
[]

At this point, the iterator function of the MyArrayList class is implemented.

Posted by I WanT To Code PHP on Sun, 28 Nov 2021 12:52:16 -0800