我为Minecraft编写插件,经常遇到这样的情况:我必须遍历3维空间中的每个块,以某种方式处理该块。例如:
for (int x = minX; x <= maxX; x++) {
for (int y = minY; y <= maxY; y++) {
for (int z = minZ; z <= maxZ; z++) {
// Do something
}
}
}
这类循环发生很多,令我感到惊讶的是,也许有一种更好的方法可以使代码更简洁,但执行速度仍然很快。我真正想做的就是遍历3维类型的每个坐标。
Bukkit API具有这样的类型-Vector
类,可以容纳x,y,z。 Vector类具有返回整数的方法,例如getBlockX
,getBlockY
和getBlockZ
。因此,我正在考虑创建这样的实用方法:
Stream<Vector> getXYZStream(minVector, maxVector)
这将返回给定的最小和最大向量之间的所有向量(x,y,z)值的流。因此,我可以这样做:
getXYZStream(minVector, maxVector).forEach(v -> doSomething);
我在这方面如何制作向量流?如果我可以编码这种方法,那么我将衡量性能上的差异,看看是否有意义。
或者有更好的方法吗?
或者我应该接受这些循环是必要的并且是最佳方法吗?
我发现了一种方法,可以使用自定义迭代器生成流,因此可以执行以下操作:
public Stream<Vector> get3dStream(Vector minVector, Vector maxVector) {
Iterator<Vector> it = new CustomIterator(minVector, maxVector);
return StreamSupport.stream(Spliterators.spliteratorUnknownSize(it, Spliterator.DISTINCT), false);
}
class CustomIterator implements Iterator<Vector> {
private Vector minVector;
private Vector maxVector;
BoundingBox b = new BoundingBox();
// constructor
CustomIterator(Vector minVector, Vector maxVector) {
// initialize cursor
this.minVector = minVector;
this.maxVector = maxVector.add(new Vector(1,1,1));
}
// Checks if the next element exists
@Override
public boolean hasNext() {
return !minVector.equals(maxVector);
}
// moves the cursor/iterator to next element
@Override
public Vector next() {
Vector r = minVector;
increment();
return r;
}
private void increment() {
// Increment the vector - this takes a lot of code to do
}
}
但是,如您所见,在自定义迭代器中跟踪next()
将需要大量代码,与这三个for循环进行比较要复杂得多,并且可能会更慢。我同意kaya3的评论,它可以隐藏一些循环,但不会更快,这是100%的要求。