在 Java 中编写通用迭代器
Writing a generic iterator in Java
当我在内存中存储我的 class AbstractState
的集合时,我遇到了内存不足的异常,所以我试图写一个 iterable/iterator。我有一点 C# 知识,但 Java 经验很少。在 C# 中,我会编写一个返回 IEnumerable<AbstractState>
的方法,但在这里似乎并不那么容易。
AbstractState
存储一对坐标,尽管根据实现的不同,对它们的操作也不同。 (它还扩展了一个通用的 MyPair<Coordinate>
。)
在 AbstractState
中,我定义了一个构造函数 AbstractState(Coordinate A, Coordinate B){super(A,B);}
。我在一些但不是所有子 classes 中覆盖了它。 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
不起作用,我无法实例化抽象 class。我想我已经接近尝试
getDeclaredConstructor(Coordinate.class, Coordinate.class).newInstance(iX.next(), iY.next());
但我收到编译器警告,提示没有此类方法。
当我投射到 T
时,我有未经检查的投射,所以怀疑这是个坏主意。有很多 iterators/iterables 是没有吸引力的,因为我会检查(通过 if
语句或 switch
)我需要哪个迭代器,这破坏了我的 OO 代码设计。
如有任何建议,谢谢
将this
传递给迭代器构造函数。 StateSpace 可以访问实例化的 T
类型,因此它可以实现确定如何 getNext()
和 hasNext()
的方法。不清楚 iX
和 iY
是什么意思。
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.
}
}
也许有帮助。
当我在内存中存储我的 class AbstractState
的集合时,我遇到了内存不足的异常,所以我试图写一个 iterable/iterator。我有一点 C# 知识,但 Java 经验很少。在 C# 中,我会编写一个返回 IEnumerable<AbstractState>
的方法,但在这里似乎并不那么容易。
AbstractState
存储一对坐标,尽管根据实现的不同,对它们的操作也不同。 (它还扩展了一个通用的 MyPair<Coordinate>
。)
在 AbstractState
中,我定义了一个构造函数 AbstractState(Coordinate A, Coordinate B){super(A,B);}
。我在一些但不是所有子 classes 中覆盖了它。 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
不起作用,我无法实例化抽象 class。我想我已经接近尝试
getDeclaredConstructor(Coordinate.class, Coordinate.class).newInstance(iX.next(), iY.next());
但我收到编译器警告,提示没有此类方法。
当我投射到 T
时,我有未经检查的投射,所以怀疑这是个坏主意。有很多 iterators/iterables 是没有吸引力的,因为我会检查(通过 if
语句或 switch
)我需要哪个迭代器,这破坏了我的 OO 代码设计。
如有任何建议,谢谢
将this
传递给迭代器构造函数。 StateSpace 可以访问实例化的 T
类型,因此它可以实现确定如何 getNext()
和 hasNext()
的方法。不清楚 iX
和 iY
是什么意思。
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.
}
}
也许有帮助。