Review: the for-each-loop

  • Java has a for-each-loop that iterates over "collection" objects:

        for ( dataType x : Collection )
        {
           // operate on x
        }
    

  • Example: an ArrayList is an iterable collection

        ArrayList<Integer> a = new ArrayList<>();
    
        a.add(1); a.add(2); a.add(3);
    
        for ( Integer i : a )
        {
            System.out.println(">>> " + i );
        }
    

DEMO: demo/11-linked-list/06-iterable/Demo.java

Using the for-each-loop with a linked list

  • It would be nice if we can write a linked list in the for-each-loop - like this:

       public static void main(String[] args)
       {
          GenericLinkedList<String> stringList =
                                   new GenericLinkedList<String>();
          stringList.addFirst("C");
          stringList.addFirst("B");
          stringList.addFirst("A");
          System.out.println(stringList); // A -> B -> C
    
          for ( String s : stringList )
              System.out.println(s);
       }
    

    Result: a compile error....

    Demo.java:15: error: for-each not applicable to expression type
          for ( String s : stringList)
                           ^
      required: array or java.lang.Iterable
    

DEMO: demo/11-linked-list/07-for-each-with-list/Demo.java

When can you use an object with a for-each-loop ?

  • We can use an ArrayList in the for-each-loop because the ArrayList is "Iterable":

        ArrayList<Integer> a = new ArrayList<>();
    
        a.add(1); a.add(2); a.add(3);
    
        for ( Integer i : a )  // ArrayList a is "Iterable"
        {
            System.out.println(">>> " + i );
        }
    

  • Being "Iterable" means a class (e.g.: ArrayList) implements the Iterable interface:

       // Implementing this interface allows an object to be 
       // the target of the "for-each loop" statement. 
    
       public interface Iterable<T>
       {
           public Iterator<T> iterator();
            // Returns an iterator (object) over elements of type T.
       }

    Documentation on Iterable:

Making our Linked List Iterable

  • Consider the GenericLinkedList.java class that we have written:

    public class GenericLinkedList<T> implements SimpleList<T>
    {
       private class Node<T>
       {
          private T item;
          private Node<T> next;
    
          ...
       }
    
       private Node<T> first;   // Start of linked list
    
       public GenericLinkedList()
       {
          first = null;
       }
    
       ....
    }
    

  • According to the Iterable<T> interface , to make the linked list Iterable, the class must implement the Iterable<T> interface

SHOW: demo/11-linked-list/99/GenericLinkedList.java

Making the Simple List iterable

  • We make the following additions to implement the Iterable<T> interface:

    public class GenericLinkedList<T> implements SimpleList<T>, Iterable<T>
    {
       private class Node<T>
       {
          private T item;
          private Node<T> next;
    
          ...
       }
    
       private Node<T> first;   // Start of linked list
    
       public GenericLinkedList()
       {
          first = null;
       }
    
       ....
    
       public Iterator<T> iterator() // Implements the Iterable<T> interface 
       {
           // Returns an iterator (object) over elements of type T.
           // We still need to figure out what to do here...
       }  
    }
    

What is an Iterator object ?

  • From the last slide, we must write the following iterator() method to make our linked list Iterable:

       public Iterator<T> iterator() // Implements the Iterable<T> interface 
       {
           // Returns an iterator (object) over elements of type T.
           // We still need to figure out what to do here...
       } 
    

  • From the definition above, we know that:

    • The iterator() method will return an Iterator<T> object

      (Because the return type is Iterator<T>)

    • From the description, we learn that this Iterator<T> object is used to "iterate over the elements of type T"

  • The Java's documentation of Iterator<T> is found here:

    • Iterator<T> is an interface

    • Therefore: an Iterator object is created using a class that implements the Iterator<T> interface !