最高效的Java数据结构,以频繁地在三维中查找值?

最高效的Java数据结构,以频繁地在三维中查找值?,java,android,performance,Java,Android,Performance,到目前为止,我从未使用过三维数据,我正在尝试实现一种结构,它允许我将对象存储在一个结构中,该结构允许我找到任何给定对象的坐标(x,y,z),找到与其相邻的任何对象,并获得所有值(房间)的列表 数据将被频繁读取,但很少更改,我的目标是Android,因此内存效率非常重要。目前,所有3个轴的边界均为0-11,但在未来,必须为轴0-250缩放(因此为250^3) 下面是我目前的代码,我读了很多相关的问题,但没有找到一个明确的答案。在java中是否有更好的数据结构/方法 public class Bui

到目前为止,我从未使用过三维数据,我正在尝试实现一种结构,它允许我将对象存储在一个结构中,该结构允许我找到任何给定对象的坐标(x,y,z),找到与其相邻的任何对象,并获得所有值(房间)的列表

数据将被频繁读取,但很少更改,我的目标是Android,因此内存效率非常重要。目前,所有3个轴的边界均为0-11,但在未来,必须为轴0-250缩放(因此为250^3)

下面是我目前的代码,我读了很多相关的问题,但没有找到一个明确的答案。在java中是否有更好的数据结构/方法

public class Building {

    private int mStartX;
    private int mStartZ;
    private Bounds mBounds;
    private Map<XYPair, Map<Integer, Room>> mRooms;

    public Building(Bounds b) {
        mBounds = b;
        mRooms = new HashMap<>();
        mStartX = Math.round(b.getMaxWidth() / 2f) -1;
        mStartZ = Math.round(b.getMaxHeight() / 2f) -1;
        Map<Integer, Room> zMap = new HashMap<>();
        zMap.put(mStartZ, new StartRoom());
        mRooms.put(new XYPair(mStartX, 0), zMap);
    }

    public Room roomAt(int x, int y, int z) {
        Room room = null;
        Map<Integer, Room> zMap = mRooms.get(new XYPair(x, y));
        if (zMap != null) {
            room = zMap.get(z);
        }
        return room;
    }

    //FIXME: There must me a more efficient structure
    public List<Room> getAdjacentRooms(Room l) {
        List<Room> adjacent = null;
        if (l != null) {
            for (int y = 0; y < mBounds.getMaxLength(); y++) {
                for (int x = 0; x < mBounds.getMaxWidth(); x++) {
                    for (int z = 0; z < mBounds.getMaxHeight(); z++) {
                        if (l.equals(roomAt(x, y, z))) {
                            adjacent = getAdjacentRooms(x, y, z);
                        }
                    }
                }
            }
        }
        return adjacent;
    }

    public List<Room> getAdjacentRooms(int x, int y, int z) {
        List<Room> adjacent = new ArrayList<>();
        if (x > 0) {
            Room room = roomAt(x-1, y, z);
            if (room != null) {
                adjacent.add(room);
            }
        }
        if (x < mBounds.getMaxWidth()) {
            Room room = roomAt(x+1, y, z);
            if (room != null) {
                adjacent.add(room);
            }
        }
        if (y > 0) {
            Room room = roomAt(x, y-1, z);
            if (room != null) {
                adjacent.add(room);
            }
        }
        if (y < mBounds.getMaxLength()) {
            Room room = roomAt(x, y+1, z);
            if (room != null) {
                adjacent.add(room);
            }
        }
        if (z > 0) {
            Room room = roomAt(x, y, z-1);
            if (room != null) {
                adjacent.add(room);
            }
        }
        if (z < mBounds.getMaxHeight()) {
            Room room = roomAt(x, y, z+1);
            if (room != null) {
                adjacent.add(room);
            }
        }
        return adjacent;
    }

    public List<Room> getAllRooms() {
        List<Room> rooms = new ArrayList<>();
        for (Map<Integer, Room> zMap : mRooms.values()) {
            rooms.addAll( zMap.values() );   
        }
        return rooms;
    }

    private final class XYPair {

        private final int mX, mY;

        public XYPair(int x, int y) {
            mX = x;
            mY = y;
        }

        public int getX() {
            return mX;
        }

        public int getY() {
            return mY;
        }

        public int hashCode() {
            return (mX * 31) ^ mY;
        }

        public boolean equals(Object o) {
            if (o instanceof XYPair) {
                XYPair other = (XYPair) o;
                return (mX == other.getX() && mY == other.getY());
            }
            return false;
        }

    }

}
公共类建筑{
私人int mStartX;
姆斯塔茨私人酒店;
私人债券;
私人地图;
公共建筑(b){
mBounds=b;
mRooms=newhashmap();
mStartX=Math.round(b.getMaxWidth()/2f)-1;
mStartZ=Math.round(b.getMaxHeight()/2f)-1;
Map zMap=newhashmap();
zMap.put(mStartZ,newstartroom());
mRooms.put(新的XYPair(mStartX,0),zMap);
}
公共房间(内x、内y、内z){
房间=空;
Map zMap=mRooms.get(新的XYPair(x,y));
如果(zMap!=null){
房间=zMap.get(z);
}
返回室;
}
//FIXME:必须有一个更有效的结构
公共列表getAdjacentRooms(l室){
列表相邻=空;
如果(l!=null){
对于(int y=0;y0){
房间=房间(x-1,y,z);
如果(房间!=null){
相邻。添加(房间);
}
}
if(x0){
房间=房间(x,y-1,z);
如果(房间!=null){
相邻。添加(房间);
}
}
if(y0){
房间=房间(x,y,z-1);
如果(房间!=null){
相邻。添加(房间);
}
}
如果(z
您的数据有多稀疏/密集?如果它相对稀疏,那么
映射将是一种节省时间和空间的数据存储方式。例如,通过
XYZCoordinate
为每个
房间
设置键。并让每个
房间
记住其当前指定的坐标,这样您就不必在整个数据结构中进行彻底搜索来确定给定房间的x/y/z坐标。
getAdjacentRooms(Room l)
方法是代码在时间上的主要低效之处,因为它在整个数组中搜索应该通过执行
Room.getCoords()
来实现的内容。因为它很少写,所以经常读。那么为什么不在每次添加房间时附加相邻的房间呢?然后将它们存储在“SortedMap adjacentRooms”中,用比较器按x,y,z排序。Aroth让房间记住我也想到了坐标,但看起来像是一个黑客,尽管目前它似乎是最好的选择,最终整个11^3网格应该被填满。安吉尔,我不知道你到底是什么意思。@NickCardoso我同意aroth的观点,每个房间都应该记住自己的坐标。这不是一个黑客;问题是坐标(房间的一个属性)存储在房间外面,隐含在数据结构中。如果内存不足,这可能是一个有效的黑客攻击,但情况似乎并非如此。我还建议您对数据结构进行某种程度的规范化—z坐标是二等坐标,我看不出有什么原因。或者是一个映射中的一个映射,或者是将XYPair更改为XYZ坐标并拥有一个映射的更明智的方法。它根本不会改变您的访问模式,地图中的同一个键(XYZ坐标)也可以存储在房间结构中。您的数据有多稀疏/密集?如果它相对稀疏,那么
映射将是一种节省时间和空间的数据存储方式。例如,通过
XYZCoordinate
为每个
房间
设置键。及