用Java编写泛型迭代器

时间:2018-04-07 23:39:51

标签: java generics iterator abstract-class ienumerable

当我将类AbstractState的一个集合存储在内存中时,我的内存异常就出现了,所以我正在尝试编写一个可迭代/迭代器。我有一些C#知识但很少有Java经验。在C#中,我会编写一个返回IEnumerable<AbstractState>的方法,但这里看起来并不那么容易。

AbstractState存储一对坐标,但根据实现情况,它们的操作会有所不同。 (它还扩展了通用MyPair<Coordinate>。)

AbstractState中,我定义了一个构造函数AbstractState(Coordinate A, Coordinate B){super(A,B);}。我在一些但不是所有的子类中重写了这一点。 Coordinate具体。这是我的可迭代:

import java.util.Iterator;

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

和我的迭代者:

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此处是Coordinate s的静态范围。)

如何正确实施next()方法? (或者,我的代码解决此问题的更好的设计是什么?)

实例化T不起作用,我无法实例化抽象类。我想我接近尝试了

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

但是我收到了编译器警告没有这样的方法。

当我投放到T时,我有未经检查的演员表,所以怀疑这是一个坏主意。拥有许多迭代器/迭代器是没有吸引力的,因为我将检查(通过if语句或switch)我需要的迭代器,这会破坏我的OO代码设计。

任何建议表示赞赏,谢谢

1 个答案:

答案 0 :(得分:1)

this传递给迭代器构造函数。 StateSpace可以访问实例化的T类型,因此它可以实现确定如何getNext()hasNext()的方法。目前尚不清楚iXiY的含义。

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);
    }
}

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.
    }
}

也许有帮助。