0

Although this code is from an algorithm text, I have a bit of a trouble regarding nested classes and interfaces - actually, 90% of my confusion arises from how this code implements the interface. Again, this question is not about the algorithm itself.

As I understand, this code uses a nested class so that it can access the private instance variables in ResizingArrayStack (this text uses a convention to declare all instance variables private for encapsulation).

The Iterable interface is this:

public Iterator<Item> { Iterator<Item> iterator(); } // ignore the quotes

and the Iterator interface is this:

public interface Iterator<Item> { boolean hasNext(); Item next(); void remove(); }

And my question is how all these connect in the code shown below.

The parent class implements the Iterable interface, but where is the Iterator interface coming directly from when ReverseArrayIterator implements Iterator? Is it coming from the Iterator instance method, or from the Iterable interface? Intuition tells me that it's implementing directly from the Iterator instance method and ultimately from the Iterable interface (kind of like how extends work?).

Sorry for my lack of OOP knowledge..this text only briefly talks about it, and I was told that I didn't have to know any of this (and I probably don't, as long as I understand the algorithms), but I HAVE TO UNDERSTAND IT lol. I just can't get this off my mind. Thanks in advance.

// from http://algs4.cs.princeton.edu/13stacks/ResizingArrayStack.java.html
import java.util.Iterator;
import java.util.NoSuchElementException;

public class ResizingArrayStack<Item> implements Iterable<Item> {
    private Item[] a;         // array of items
    private int N;            // number of elements on stack

    // create an empty stack
    public ResizingArrayStack() {
        a = (Item[]) new Object[2];
    }

    public boolean isEmpty() { return N == 0; }
    public int size()        { return N;      }



    // resize the underlying array holding the elements
    private void resize(int capacity) {
        assert capacity >= N;
        Item[] temp = (Item[]) new Object[capacity];
        for (int i = 0; i < N; i++) {
            temp[i] = a[i];
        }
        a = temp;
    }

    // push a new item onto the stack
    public void push(Item item) {
        if (N == a.length) resize(2*a.length);    // double size of array if necessary
        a[N++] = item;                            // add item
    }

    // delete and return the item most recently added
    public Item pop() {
        if (isEmpty()) { throw new RuntimeException("Stack underflow error"); }
        Item item = a[N-1];
        a[N-1] = null;                              // to avoid loitering
        N--;
        // shrink size of array if necessary
        if (N > 0 && N == a.length/4) resize(a.length/2);
        return item;
    }


    public Iterator<Item> iterator()  { return new ReverseArrayIterator();  }

    // an iterator, doesn't implement remove() since it's optional
    private class ReverseArrayIterator implements Iterator<Item> {
        private int i = N;
        public boolean hasNext()  { return i > 0;                               }
        public void remove()      { throw new UnsupportedOperationException();  }

        public Item next() {
            if (!hasNext()) throw new NoSuchElementException();
            return a[--i];
        }
    }

}
nhahtdh
  • 55,989
  • 15
  • 126
  • 162
user1164937
  • 1,979
  • 2
  • 21
  • 29

1 Answers1

3

The parent class implements the Iterable interface, but where is the Iterator interface coming directly from when ReverseArrayIterator implements Iterator?

That question doesn't make much sense. The Iterator interface "comes from" the Java SE class libraries ('cos your code imports it), and it is implemented by the ReverseArrayIterator class. And at runtime, a call to the ResizingArrayStack.iterator() method creates an instance of the ReverseArrayIterator class when you call it.

Intuition tells me that it's implementing directly from the Iterator instance method and ultimately from the Iterable interface (kind of like how extends work?).

The connection with the Iterable interface is that the outer class implements it. But Iterable just "means" that there is an iterator() method that can be called to create an Iterator instance of the appropriate type. There is no special "kind of like how extends work" magic happening. It is all just classes implementing interfaces in this example.

The other "different" thing about this is that ReverseArrayIterator is a nested class, and can therefore access the private state of the parent object. In this case a and N.

What is going on here is that a number of independent things (language features and design patterns) are being combined to achieve a particular overall effect. That overall effect is to make it possible to iterate the elements of the stack using a "for each" loop.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
  • Thanks. It took me a while to get it (with no prior OOP experience), but I think I understand enough of what you said to see what the code is trying to do. – user1164937 Jun 11 '12 at 04:16