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