1

I was getting out of memory exceptions when I stored a collection of my class AbstractState in memory, so I am trying to write an iterable/iterator. I have a bit of C# knowledge but little Java experience. In C# I would write a method returning an IEnumerable<AbstractState>, but it doesn't seem so easy here.

AbstractState stores a pair of coordinates, although depending on the implementation, the operations on them differ. (It also extends a generic MyPair<Coordinate>.)

Within AbstractState, I define a constructor AbstractState(Coordinate A, Coordinate B){super(A,B);}. I override this in some but not all sub-classes. Coordinate is concrete. Here is my iterable:

import java.util.Iterator;

public class StateSpace<T extends AbstractState> implements Iterable<T> {
    @Override
    public Iterator<T> iterator() {
        return new StateIterator();
    }
}

and my Iterator:

public class StateIterator<T extends AbstractState> implements Iterator<T> {
    private Iterator<Coordinate> iX, iY;

    StateIterator(){
        iX = Main.GRID.iterator();
        iY = Main.GRID.iterator();
    }

    @Override
    public boolean hasNext() {
        return iX.hasNext() || iY.hasNext();
    }

    @Override
    public T next() {
        return null;
    }
}

(GRID here is a static range of Coordinates.)

How can I implement the next() method correctly? (Or, what is a better design for my code to solve this problem?)


Instantiating a T does not work, and I cannot instantiate an abstract class. I think I was close by trying

getDeclaredConstructor(Coordinate.class, Coordinate.class).newInstance(iX.next(), iY.next());

but I got a compiler warning for no such method.

I had unchecked casts when I casted to a T, so suspect that this is a bad idea. Having many iterators/iterables is unappealing, as I would be checking (via if statements or a switch) which iterator I need, which undermines my OO code design.

Any suggestions appreciated, thanks

2
  • what do you mean by "when I stored a collection of my class AbstractState in memory"? Please clarify: Do you already have a collection of AbstractState in memory and you get a memory exception when you add to it? in that case iterating it won't help you. Commented Apr 9, 2018 at 5:58
  • @inor sorry - just saw this. Previously I created the collection of AbstractState to be used later (in for loops). I could not even create it because it was too large. So I would like to iterate through an iterable so that storing every AbstractState in memory is not needed Commented Apr 13, 2018 at 14:39

1 Answer 1

1

Pass this to the iterator constructor. The StateSpace has access to the instantiated T type, and so it can implement methods to determine how to getNext() and hasNext(). It's not clear what iX and iY are about.

import java.util.Iterator;

public class StateSpace<T extends AbstractState> implements Iterable<T> {
    List<T> types;
    int pos;

    public StateSpace() {
        types = new ArrayList<>();
    }
    public void add(T type) {
        types.add(type);
    }
    T getNext() {
        return types.get(pos++);
    }
    boolean hasNext() {
         return pos < types.size()-1;
    }
    @Override
    public Iterator<T> iterator() {
        return new StateIterator(this);
    }
}

and

public class StateIterator<T extends AbstractState> implements Iterator<T> {
    private Iterator<Coordinate> iX, iY;
    private StateSpace<T> stateSpace;

    StateIterator(StateSpace<T> stateSpace){
        this.stateSpace = stateSpace;
        iX = Main.GRID.iterator();
        iY = Main.GRID.iterator();
    }

    @Override
    public boolean hasNext() {
        return iX.hasNext() || iY.hasNext();
    }

    @Override
    public T next() {
        return stateSpace.getNext(); // or whatever.
    }
}

maybe helps.

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks for reply. next() must return a T, but stateSpace is of type StateSpace<T>. I tried putting a method in StateSpace that returns a T, but have the same problems
Right, sorry, assuming StateSpace saves or has access to a type T then stateSpace should be able to getNext(); Updated.
Ahaa, that makes sense: if you can't getNext then it isn't "Iterable" really. I'll need to keep track of the current AbstractSpace so I can iterate to the next

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.