Question

NOTE: In real life situation I would use an appropriate Java collection but in this task I would like to do everything form scratch.

I've done my Googling here on SO and on the rest of the web, but didn't find exactly what I was looking for.

It's my understanding that for-each loop can operate on any class that implements iterable interface and at the same time this class does not have to implement iterator. Am I right here?

Let say, I have the following two classes that are not explicitly derived from any other class.

public class Pile {

   private Thing aThing = new Thing(); 

   // other varibles
   // constructor
   // other methods (including getters and setters)
}

and

public class Thing {

   private object value;   // Payload
   private Thing link1;    // variables that enable awareness
   private Thing link2;    // of other Thing objects
                           // For example, link1 could be reference to the previous object
                           // and link2 - to the next

   // other varibles
   // constructor
   // other methods (including getters and setters)
}

In this example, Pile would be a double-linked List. But it does not have to.

My goal would be to create IterablePile class through inheritance.

public class IterablePile extends Pile {
}

The only requirement of Iterable interface is to implement Iterator method.

And here I'm stumped. It seems that all examples (or at least those that I found so far) immediately assume that my class is derived from one of the Java collections (for example ArrayList).

What if this not the case? What exactly needs to be done in such case? What steps need to be taken?

Can you point me in the right direction (preferably not writing the code itself)?

And one more question. Will the situation change if Thing is a private inner class of Pile?

It seems to me that I'm missing something basic but can't put my finger on it.

Was it helpful?

Solution

If only your IterablePile needs to be iterated, then you just have to implement the Iterable interface that will provide an Iterator. Here's a basic example:

public class IterablePile extends Pile implements Iterable<Thing> {
    //current class implementation...
    private class MyIterablePileIterator implements Iterator<Thing> {
        private Thing thing;
        private MyIterablePileIterator(Thing thing) {
            this.thing = thing;
        }
        @Override
        public boolean hasNext() {
            //add the implementation...
            return (thing.getLink1() != null || thing.getLink2() != null);
        }
        @Override
        public Thing next() {
            //add the implementation...
            //since it is a tree structure, you could use a Queue<Thing>
            //to implement prefix, infix or postfix navigation
        }
        @Override
        public void remove() {
            //add the implementation...
            //in case you don't want to implement it, you can leave it blank
            //or throw new UnsupportedOperationException("never remove!")
        }
    }
    @Override
    public Iterator<Thing> iterator() {
        return new MyIterablePileIterator(getAThing());
    }
}

Still, I would find very odd that only your IterablePile would be iterable, while the Pile won't. Note that your code should be oriented to interfaces (or abstract/super classes) instead of specific implementations. Anyway, this should do.

More info:

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top