Iterator iterator traverses Collection [java]

Posted by maxsslade on Thu, 02 Dec 2021 20:19:49 +0100

Traversing Collection with Iterator

  • Our Iterator is an interface -- what we can call an iterator interface

  • An instance object of the implementation class of the Iterator interface is what we call an iterator (an iterator is really one of the design patterns)

  • We created an instance object of the implementation class of the Iterator interface to traverse elements in the collection

GOF defines an iterator pattern as providing a way to access each element of a container object without exposing its internal details.
  • That is, our iterator pattern (or what we call iterators) is built for containers
    • Our iterator is similar to "bus ticket salesperson", "train attendant", "flight attendant". That is to do the work of checking tickets. Each element and element should be checked (corresponding to everybody getting on the bus in real life, check to see if everybody is checking tickets, if they are checked on the bus).

How do I get an iterator? That is, how do I get the instantiated object of the implementation class of the Iterator interface?

  • We can get the instantiation object of the implementation class of the Iterator interface by calling the iterator() method in the Collection interface
    • The Iterator() method in a Collection is an abstract method that is used as an iterator created by calling the Iterator() method in a concrete implementation class of the Collection interface

eg:

package iterator;

import java.util.Collection;
import java.util.ArrayList;
import java.util.Iterator;

public class IteratorDemo1 {
    public static void main(String[] args) {
        Collection c1 = new ArrayList();
        c1.add(1234);
        c1.add("abc");
        /*
        Here the Iterator is a reference to our iterator, and the iterator() method in our Collection interface is actually an abstract method, and at this point we are
        We arrived at our iterator (that is, the instantiated object of the implementation class of the Iterator interface) by calling the override method in the ArrayList class of our Collection interface's implementation class
         */
        Iterator iterator = c1.iterator();
    }
}

  • In our example, the iterator() method overridden in the implementation subclass ArrayList of the Collection interface is called in a polymorphic form

Summary:

  • Our iterator object was created by calling the Iterator() method in the concrete implementation class of the Collection interface
  • The Iterator() method in the Collection interface is declared as an abstract method

So how do we use iterators to traverse collections?

First, we'll use two methods in our iterator:

  1. hasNext();
  2. next();
  • Here we describe three ways to iterate through a set using an iterator

Mode 1:

We call the next() method of the implementation class object (that is, our iterator) of the Iterator interface many times

eg:

package iterator;

import java.util.Collection;
import java.util.ArrayList;
import java.util.Iterator;

public class IteratorDemo2 {
    public static void main(String[] args) {
        Collection c1 = new ArrayList();
        c1.add(1234);
        c1.add("abc");
        c1.add(new Dog("Little Black",2));
        c1.add(false);
        Iterator iterator = c1.iterator();
        System.out.println(iterator.next());
        System.out.println(iterator.next());
        System.out.println(iterator.next());
        System.out.println(iterator.next());
    }
}
class Dog{
    private String name;
    private int age;
    public Dog(){

    }
    public Dog(String name,int age){
        this.name=name;
        this.age= age;
    }
    public boolean equals(Object obj){
        if(this==obj)return true;
        else if(obj == null||this.getClass()!= obj.getClass())
            return false;
        else {
            Dog dog = (Dog) obj;
            if (dog.name.equals(name) && dog.age == age) {
                return true;
            }
            return false;
        }
    }

    @Override
    public String toString() {
        return "Dog{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

  • Here we refer to a next() method in Iterator, which temporarily assumes that we start traversing the binding elements from the first place, where we can assume that the instantiated object (i.e., the iterator) of our Iterator interface's implementation class is a pointer, and that the iterator object was the one we started with when we created the iterator object (that is, our pointer) Just above the first element in our collection, that is, pointing at the empty place, note: here our iterator object starts not at the position of the first element in the collection, but at the position of our first element, that is, our newly created iterator object is above the empty position in front of the first element in our collection
    • Our next() method works in two steps:
      1. Pointer down (that is, our iterator down)
      2. Return the set element at a later position down
    • So so that we start by traversing the first element, we can also better understand why our iterator (that is, the pointer) starts by pointing to the previous position of the first element in our collection

Be careful:

In the example above, we created a Collection implementation class object with only four elements. What happens if we use it again?

  • At this point, if you compare our array to the following, if it's an array, an ArrayIndexOutOfBoundException will be thrown.
  • We'll throw an exception here too, but instead of throwing an array subscript out of bounds, we'll throw a NoSuchElementException.

Mode 2:

Add for loop traversal to the first way

  • Use a set object.size - that is, set elements to control the number of forloops and then traverse through the next() method inside the forloop
    • This way, to some extent, greatly reduces the likelihood that we will have NoSuchElementException when traversing a set element

eg:

package iterator;

import java.util.Collection;
import java.util.ArrayList;
import java.util.Objects;
import java.util.Iterator;

public class IteratorDemo3 {
    public static void main(String[] args) {
        Collection c1 = new ArrayList();
        c1.add("abc");
        c1.add(1234);
        c1.add(new Dog2());
        c1.add(false);
        c1.add(1.3);
        Iterator iterator = c1.iterator();
        /*
        At this point, we use the for loop to control the number of times, and then use the next() method inside the for loop to traverse the elements in the set, which to some extent can greatly reduce US
        Possibility of NoSuchElementException (element not found)
         */
        for(int i=0 ; i<c1.size() ; i++){
            System.out.println(iterator.next());
        }
    }
}
class Dog2{
    private String name;
    private int age;
    public Dog2(){

    }

    public Dog2(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Dog2 dog2 = (Dog2) o;
        return age == dog2.age &&
                Objects.equals(name, dog2.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }

    @Override
    public String toString() {
        return "Dog2{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

Summary:

  • The first two methods are rarely used in our actual programming, and most of the time they are used to traverse the elements of a collection in the following three ways

Mode 3:

Since we mentioned two methods in traversing a set earlier, only the next() method has been designed in the first and second modes. Obviously, we want to use the two methods together. At this point, we put forward the third mode.

  • The third way is to use the while loop, then let our hasNext() method be used as the criterion for the loop, and then within the while loop, use the next() method to iterate through the elements in the set.

eg:

package iterator;

import java.util.Collection;
import java.util.ArrayList;
import java.util.Objects;
import java.util.Iterator;

public class IteratorDemo4 {
    public static void main(String[] args) {
        Collection c1 = new ArrayList();
        c1.add(1234);
        c1.add("abc");
        c1.add(false);
        c1.add(new Dog3());
        c1.add(1.5);
        /* 
        Here we create an iterator object
         */
        Iterator iterator =  c1.iterator();
        /*
        Here we use mode three to traverse our collection elements, which is the way most of our actual programming uses to traverse them.
        And this way we can completely avoid NoSuchElementException
         */
        while(iterator.hasNext()){
            System.out.println(iterator.next());
        }
    }
}
class Dog3{
    private String name;
    private int age;
    public Dog3(){
        
    }
    public Dog3(String name,int age){
        this.name = name;
        this.age = age;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Dog3 dog3 = (Dog3) o;
        return age == dog3.age &&
                Objects.equals(name, dog3.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }

    @Override
    public String toString() {
        return "Dog3{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
  • Then the third way is how to execute?
    • First, what are the exit conditions for our while loop? When does our hasNext() method return false when it exits when it executes as false? The hasNext() method is to determine if there are elements in the next position of the element to which our pointer (iterator) points. If there are elements, return a true. If there are no elements in the next position, then return false. That is, when there are elements in the next position of the element to which our iterator points, we enter the while loop and use next() The method traverses through the next element pointed to by the iterator until the last time our hasNext() method determines that the next location is null, it exits the while loop, and from this null element it will no longer traverse, and there will be no exceptions (NoSuchElementException found)

Summary:

Popular:

  1. Our hasNext() method is to determine if there are elements in our collection that have not yet been traversed and return a true if there is one.
  2. Our next() method is to traverse elements in our collection

The specific hasNext() method and how our next() method works are explained in this article and will be analyzed in detail later.

  • We use the iterator Iterator interface when traversing elements in a collection
  • Two methods are involved in our set traversal (1. hasNext() method and 2. next() method in the Iterator interface)
  • Three pairs of elements in a collection are traversed in our actual programming

  • Iterator is only used to traverse a Collection, not a Map.

Topics: Java Container