Reputation:
I want to make an iterator()
method in my Prison
class but to do that, I want to make a new class that will contain the boolean hasNext()
and PrisonCell next()
methods of an iterator that will implement a certain interface.
package iterator;
import java.util.Iterator;
public class Driver {
public static void main(String args[]) {
Prison prison= new Prison(5);
Iterator<PrisonCell> iter;
prison.addCell(new PrisonCell("A", 3));
prison.addCell(new PrisonCell("B", 9));
prison.addCell(new PrisonCell("C", 6));
iter= prison.iterator(); //I want to make the iterator() method in my Prison class
while (iter.hasNext())
System.out.println(iter.next());
}
/**output here would be:
Name: A, numPrisoners: 3
Name: B, numPrisoners: 9
Name: C, numPrisoners: 6
**/
}
package iterator;
public class PrisonCell { //how would I implement the Iterable<> iterface here?
private String name;
private int numPrisoners;
public PrisonCell(String name, int numPrisoners) {
this.name= name;
this.numPrisoners= numPrisoners;
}
public String toString() {
return "Name: " + name + ", numPrisoners: " + numPrisoners;
}
}
package iterator;
public class Prison{
PrisonCell prisonCells[];
int numPrisonCells;
public Prison(int size) {
prisonCells= new PrisonCell[size];
numPrisoners= 0;
}
// just do nothing if the array is full
public void addCell(PrisonCell newPrisonCell) {
if (numPrisonCells < prisonCells.length)
prisonCells[numPrisonCells++]= newPrisonCell;
}
//how do I write iterator() method here??
}
package iterator;
public class Iterator<PrisonCell>//is it supposed to implement an interface here?
//which fields here?
public Iterator() //constructor here
//I think boolean hasNext() and PrisonCell next() methods go here?
Upvotes: 0
Views: 4456
Reputation: 234795
The Iterable
interface is usually implemented by a collection of some sort. In your case, it is the Prison
class, not the PrisonCell
that could be declared to implement Iterable<PrisonCell>
.* It would need to implement a single method: iterator()
, which would return an Iterator<PrisonCell>
.
What object to return? One easy way would be to simply wrap the array in a List
and ask the List
to return an Iterator
:
public class Prison implements Iterable<PrisonCell> {
PrisonCell prisonCells[];
. . .
public Iterator<PrisonCell> iterator() {
return Arrays.asList(prisonCells).iterator();
}
}
(You might consider changing prisonCells
from a PrisonCell[]
to a List<PrisonCell>
; something I recommend. You could then ask it directly to return an Iterator
.)
Alternatively, write your own class that implements the Iterator
interface methods. (This is typically done by a private inner class of the collection class, since the iterator usually accesses the internal data structures of the collection—something that should not be exposed in a public api.) It should probably throw an exception for the remove()
method, since that operation would normally not be supported for a collection backed by an object array. (The Iterator
returned by a List
constructed by Arrays.asList()
behaves in this way.)
Here's a quick attempt at such an inner class. I wrote it under the assumption that the only the first numPrisonCells
elements of the prisonCells
array are valid:
public class Prison implements Iterable<PrisonCell> {
PrisonCell prisonCells[];
int numPrisonCells;
. . .
public Iterator<PrisonCell> iterator() {
return new PrisonIterator();
}
private class PrisonIterator implements Iterator<PrisonCell> {
private int index;
PrisonIterator() {
index = -1;
}
public boolean hasNext() {
return index < numPrisonCells - 1;
}
public PrisonCell next() {
if (index < numPrisonCells - 1) {
return prisonCells[++index];
} else {
throw new NoSuchElementException();
}
}
public void remove() {
// you could actually implement something here
throw new UnsupportedOperationException();
}
}
}
Note that this is not a very robust iterator implementation; in particular, it could skip or repeat elements if the prisonCells
array was modified during iteration. The Java Collections Framework addresses this by having each collection object maintain an internal long
modification count and when each iterator is constructed, it initializes its own copy of the modification count. Then at each method call to the iterator, it checks to see that the collection's mod count matches its internal copy and, if not, throws a ConcurrentModificationException
.
*Of course, you might want to have PrisonCell
implement Iterable<Prisoner>
. :)
Upvotes: 2