Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Return an iterator

Searching for info about the iterator, I found only examples that showed how to iterate over a collection, and not returning the Iterator, like I want to do.

I am practicing for the exam, so I'm trying out some programming excercises to prepare myself, and this one is about the iterator pattern. I want to implement the getKnightPositionIterator, . You can see the code below. This code is not mine, I found this.

package iterator;        
import java.util.*;

public class Position {

    /** return an iterator that will return all positions
     * that a knight may reach from a given starting position.
     */
    public static Iterator<Position> getKnightPositionIterator(Position p) {    


        return null;
    }


    /** create a position. 
     * @param r the row
     * @param c the column
     */
    public Position(int r, int c) { 
        this.r = r; this.c = c; 
    }

    protected int r;
    protected int c;

    /** get the row represented by this position.
     * @return the row.
     */
    public int getRow() { return r; }

    /** get the column represented by this position.
     * @return the column.
     */
    public int getColumn() { return c; }

    public boolean equals(Object o) {
        if (o.getClass() != Position.class) { return false; }
        Position other = (Position) o;
        return r==other.r && c==other.c;
    }

    public int hashCode() {
        // works ok for positions up to columns == 479
        return 479*r+c;
    }

    public String toString() {
        return "["+r+","+c+"]";
    }
}

How ever, I figure that I have to create an Iterator to return, so, so far, this is my attemp.

public static Iterator<Position> getKnightPositionIterator(Position p) {    
    Iterator<Position> knightPosIter = Position.getKnightPositionIterator(p);

    for(Iterator<Position> positions = knightPosIter; positions.hasNext(); ) {
        //What should I write here?
    }

    return knightPosIter;
}
like image 815
user1960836 Avatar asked Feb 15 '23 05:02

user1960836


1 Answers

First, make your class implement Iterable interface

public class Position implements Iterable<Position>

and write the public Iterator<Positions> iterator(); method as outlined below instead of providing a static method in your example.

As you actually need to compute a collection of reachable positions in one way or another, you will need a structure to hold it. Any such structure will normally be iterable and, thus, will have an iterator method. So a lazy implementation could look like this:

@Override
public Iterator<Position> iterator()
{
    // make sure this returns e.g. Collections.unmodifiableList
    Collection<Position> positions = computeReachablePositions(); 
    return positions.iterator();
 }

In case you have some other structure to compute and store your positions that is not iterable (not advisable), implement an iterator from scratch as follows (an array of positions assumed):

@Override
public Iterator<Position> iterator()
{
    // must be final to be accessible from the iterator below
    final Position[] positions = computeReachablePositions();

    return new Iterator<Position>() {

        int index = 0;

        @Override
        public boolean hasNext()
        {
            return index < positions.length;
        }

        @Override
        public Position next()
        {
            if (hasNext())
            {
                Position value = positions[index];
                index++;
                return value;
            }
            throw new NoSuchElementException("No more positions available");
        }

        @Override
        public void remove()
        {
            throw new UnsupportedOperationException("Removals are not supported");
        }};
}
like image 187
Oleg Sklyar Avatar answered Feb 17 '23 03:02

Oleg Sklyar