问题
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.
回答1:
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:
- What does it mean to "program to an interface"?
来源:https://stackoverflow.com/questions/18992132/how-to-make-a-class-which-is-not-a-descendant-of-collection-compatible-with