Java 设计查找映射

Java 设计查找映射,java,dictionary,Java,Dictionary,我在设计正确的映射时遇到问题 我正在开发一个自上而下的rpg游戏,在运行时只看到地图的一部分(区块)——当从一个区块移动到另一个区块时,会加载新的区块数据 根据我的位置,会加载不同的数据 目前我的代码看起来像这样(但肯定更长) 问题是此代码不易阅读,不易维护。关于如何做得更好有什么想法吗 我在考虑使用Map如果您使用点类并实现等于和hashcode,则可以将它们用作Map中的键 现在,实际的查找机制折叠为: static final Map<Point, Integer> looku

我在设计正确的映射时遇到问题

我正在开发一个自上而下的rpg游戏,在运行时只看到地图的一部分(区块)——当从一个区块移动到另一个区块时,会加载新的区块数据

根据我的位置,会加载不同的数据

目前我的代码看起来像这样(但肯定更长)

问题是此代码不易阅读,不易维护。关于如何做得更好有什么想法吗


我在考虑使用
Map如果您使用
类并实现
等于
hashcode
,则可以将它们用作Map中的键

现在,实际的查找机制折叠为:

static final Map<Point, Integer> lookup = new HashMap<>();

static {
    // Looks a lot like your case statement eh?
    lookup.put(new Point(1248, 1247), 512);
    lookup.put(new Point(1248, 1248), 528);
    lookup.put(new Point(1248, 1249), 544);
    lookup.put(new Point(1249, 1247), 513);
    lookup.put(new Point(1249, 1248), 529);
    lookup.put(new Point(1249, 1249), 545);
    // Could also be populated by other statics.
}

public static final int getChunkIdForPos(int x, int y) {
    Integer got = lookup.get(new Point(x, y));
    return got != null ? got : 161;
}

好的,首先要做的是:我将地图的范围从10.000x10.000限制为256x256

  • 代码仍然是不可维护的
  • 代码仍然是不可扩展的
  • 最好的性能仍然是使用开关/外壳
正确的处理方法是使用代码生成器。在一个单独的项目中,我创建了一个worldmap编辑器,它可以让我看到组合中的所有块。映射完成后(提示:现在可以保存/加载映射),代码发射器将为您生成一个类

神奇之处在于codeEmitter类:

int[][] worldMap = new int[256][256]; //generated via GUI
File file = new File(fileName);
BufferedWriter br = new BufferedWriter(new FileWriter(file));

//writing header

for (int dy = 0; dy < 256; dy++) {
    br.write("    public static int row_"+dy+"(int x){\n");
    br.write("        switch (x) {\n");
    for (int dx = 0; dx < 256; dx++) {
        br.write("        case " + dx + ": return " + worldMap[dx][dy] + ";\n");
    }
    br.write("        default: return 0;\n");
    br.write("        }\n");
    br.write("    }\n");
    br.write("\n");
}

//writing trailer

如果你用地图,有多少人“死了”你希望有哪些关键点?如何在每个地图块中封装可访问的地图块?我想一个至少有10.000 x 10.000块的地图。这个想法是,地图块可以由其他玩家提供,并有助于创建世界的一部分。如果我使用问题中描述的switch语句,则不会创建任何对象,结果是即时获得的-我想不出任何更好的方法来实现这一点,但这肯定会清理我的代码。@MartinFrank-Java旨在高效地处理对象,因此除非您在某些嵌入式环境或内存较低的情况下工作,否则成本可以忽略不计。其价值在于以少量内存为代价节省程序员时间。注意:
static
初始化只发生一次。@MartinFrank-The
case
方法的时间开销非常小,但是
HashMap
查找是
O(1)
并且速度非常接近。这是一款android应用程序,我的设计目的是在旧设备上工作(Android2.3)。。。这就是我为什么要考虑的原因我认为干净的代码和维护是选择您的解决方案的原因,即使我不确定是否有更好的方法。。。(给我一天左右,我会接受的)
public static class Point {

    final int x;
    final int y;

    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }

    @Override
    public String toString() {
        return "{" + x + "," + y + '}';
    }

    @Override
    public int hashCode() {
        int hash = 5;
        hash = 97 * hash + this.x;
        hash = 97 * hash + this.y;
        return hash;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final Point other = (Point) obj;
        if (this.x != other.x) {
            return false;
        }
        if (this.y != other.y) {
            return false;
        }
        return true;
    }

}
int[][] worldMap = new int[256][256]; //generated via GUI
File file = new File(fileName);
BufferedWriter br = new BufferedWriter(new FileWriter(file));

//writing header

for (int dy = 0; dy < 256; dy++) {
    br.write("    public static int row_"+dy+"(int x){\n");
    br.write("        switch (x) {\n");
    for (int dx = 0; dx < 256; dx++) {
        br.write("        case " + dx + ": return " + worldMap[dx][dy] + ";\n");
    }
    br.write("        default: return 0;\n");
    br.write("        }\n");
    br.write("    }\n");
    br.write("\n");
}

//writing trailer
 //this part of genCode is not explained above
 public static final int getIdForPos(int x, int y, int area){
    switch (y) {
    case 0: return row_0(x);
    case 1: return row_1(x);
    //.. lots of rows
    default: return 0;
    }
 }

 //but this part is generated with the code above
 public static int row_0(int x){
    switch (x) {
    case 0: return 4711;
    case 1: return 815;
    //.. lots of columns
    default: return 0;
    }
}