Java 对该存储数据运行测试的最有效方法

Java 对该存储数据运行测试的最有效方法,java,Java,对不起,我的标题信息不太丰富,我想不出更好的了。当我说高效时,我指的是不是cpu密集型的代码 问题: 想象一下,一艘3D宇宙飞船是由积木制成的,就像一艘内置的地雷船。我想将此形状图中每个区块的位置存储在自制的船舶类别中 为此,我使用了私有列表锁船舶类别内部。Shipplock在这里是一个自制的类,它以向量Vec3(intx,inty,intz)的形式持有一个位置,以及一些与这个问题无关的其他信息 但现在我想在船上做个测试。船舶是否在某个测试位置(x、y、z)上包含船闸,如果是,则返回该船闸。然而

对不起,我的标题信息不太丰富,我想不出更好的了。当我说高效时,我指的是不是cpu密集型的代码

问题: 想象一下,一艘3D宇宙飞船是由积木制成的,就像一艘内置的地雷船。我想将此形状图中每个区块的位置存储在自制的船舶类别中

为此,我使用了
私有列表锁船舶类别内部。Shipplock在这里是一个自制的类,它以向量
Vec3(intx,inty,intz)
的形式持有一个位置,以及一些与这个问题无关的其他信息

但现在我想在船上做个测试。船舶是否在某个测试位置(x、y、z)上包含船闸,如果是,则返回该船闸。然而,我还没有找到一种有效的方法来做到这一点。在整个列表中循环,并根据testposition测试每个位置是非常昂贵的,我希望它能更快

因此,我决定制作一个
映射图来存储信息。钥匙在船闸的位置。我可以简单地执行
shipplocksmap.get(testPosition)
,如果船的船闸位于该位置,它将返回正确的船闸。如果不是,它将返回null

这似乎正是我想要的,直到我移动了船,所有船闸都有了新的位置。我在这里了解到,如果作为关键点提供的对象发生变化,则关键点位于地图中。因此,如果我现在使用
shipplocksmap.get(testPosition)
使用移动船中的位置,它将返回null,因为键仍然是旧位置。(抱歉,如果让人困惑,我不知道如何更好地解释)

问题: 我在这里要问的问题是:如果一艘船可以容纳上万个船闸,那么测试它是否包含具有特定位置的船闸的最有效方法是什么。我应该以什么方式储存船上的船闸,这样支票才能有效地进行

代码: 如果有人想看,这里是船和船闸类的代码

public class ShipBlock 
{
    public Vec3 position;
    public String shipBlockType;

    public ShipBlock(Vec3 position, String shipBlockType)
    {
        this.position= position;
        this.shipBlockType = shipBlockType;
    }
}

public class Ship 
{
    private Map<Vec3, ShipBlock> shipBlocksMap;

    public Ship(Map<Vec3, ShipBlock> shipBlocksMap)
    {
        this.shipBlocksMap = shipBlocksMap;
    }

    public ShipBlock containsShipBlock(Vec3 position)
    {
        return shipBlocksMap.get(position);
    }
}
公共级船闸
{
公共Vec3职位;
公共字符串类型;
公共船闸(Vec3位置,字符串船闸类型)
{
这个位置=位置;
this.shipplockType=shipplockType;
}
}
公船
{
私人地图;
公共船舶(地图船闸地图)
{
this.shipplocksmap=shipplocksmap;
}
公共船闸包含船闸(Vec3位置)
{
返回船闸MAP.get(位置);
}
}

我认为最重要的设计更改是保存模块相对于船舶位置的位置

这样,当船舶移动时,您不需要更改块的键,并且可以轻松地使用
映射Shipplocksmap
进行恒定时间测试,其中键是相对位置。 您可以通过计算(概念上)
relative\u block\u pos=absolute\u block\u pos-ship\u pos
来获得相对位置

这意味着您需要存储船的位置。 作为一个选项,您可以简单地选择船舶的第一个区块作为船舶的位置,因此第一个区块始终具有坐标
(0,0,0)


通过这种方式,更改所有模块的坐标减少到最小(但在大多数情况下不需要)。

我认为最重要的设计更改是保存模块相对于船舶位置的位置

这样,当船舶移动时,您不需要更改块的键,并且可以轻松地使用
映射Shipplocksmap
进行恒定时间测试,其中键是相对位置。 您可以通过计算(概念上)
relative\u block\u pos=absolute\u block\u pos-ship\u pos
来获得相对位置

这意味着您需要存储船的位置。 作为一个选项,您可以简单地选择船舶的第一个区块作为船舶的位置,因此第一个区块始终具有坐标
(0,0,0)


这样,更改所有块的坐标将减少到最小值(但在大多数情况下不需要)。

空间分区树可能是您的最佳选择;看见你的模型宇宙的一半可能是空的,在许多这样的结构中,一次测试就能揭示这一点,并有助于未来的测试,直到宇宙的一半以某种方式发生变化。维护结构的责任在您身上,但听起来对结构的更改比测试多。另一种方法可能是使用meta Ball或Voronoi外壳包围块或块簇,以便将每个测试量减少为单个测试

空间分区树可能是您的最佳选择;看见你的模型宇宙的一半可能是空的,在许多这样的结构中,一次测试就能揭示这一点,并有助于未来的测试,直到宇宙的一半以某种方式发生变化。维护结构的责任在您身上,但听起来对结构的更改比测试多。另一种方法可能是使用meta Ball或Voronoi外壳包围块或块簇,以便将每个测试量减少为单个测试

你不能在移动块时,将其从地图中删除并重新插入到新位置吗?也许你可以给船一个位置,然后相对于船的位置存储船的所有块,因此,如果船移动,你只需要修改船的位置,而不需要修改所有的船块。@Diego Martinoia不是这样的,如果船上有很多积木,效率会很低吗?每次船舶移动时,对每个区块使用.remove()和.put()。如果存储每个区块,则为“是”。但是,如果像其他人指出的那样,所有的块都一起移动,哟