这是我需要在Conway的生命游戏实现中使用的简化代码片段。我有一个HashMap,其中存储了Coord Objects(生命游戏中的单元格)。 Coord对象是X,Y坐标对,我想在简单的2D网格上打印。
我的printGrid(HashMap<Coord, Integer> map)
方法存在问题,主要是:
是否有更简单,更优雅的方式在2维网格上打印Coord对象?
如果没有,有没有办法检查HashMap中是否存在具有给定X,Y参数的Coord对象,而没有为网格上的每个X,Y位置创建Coord对象的实例,就像我'我在这里做:
if (map.containsKey(new Coord(column,row))) {
grid += map.get(new Coord(column,row));
} else {
grid += "#";
}
代码:
public class Main {
static class Coord {
int x;
int y;
public boolean equals(Object o) {
Coord c = (Coord) o;
return c.x == x && c.y == y;
}
public Coord(int x, int y) {
super();
this.x = x;
this.y = y;
}
public int hashCode() {
return x * 3 + y * 5;
}
}
public static String printGrid(HashMap<Coord, Integer> map) {
int grid_width = 10;
int grid_height = 10;
String grid = "";
for(int row =0; row < grid_height; row++) {
for(int column=0; column< grid_width; column++) {
if(map.containsKey(new Coord(column,row))) {
grid += map.get(new Coord(column,row));
} else {
grid += "#";
}
}
grid += "\n"; // next row
}
return grid;
}
public static void main(String args[]) {
HashMap<Coord, Integer> map = new HashMap<Coord, Integer>();
map.put(new Coord(0, 0), 1);
map.put(new Coord(1, 2), 5);
map.put(new Coord(3, 4), 1);
map.put(new Coord(4, 5), 3);
map.put(new Coord(4, 6), 2);
System.out.println(printGrid(map));
}
}
答案 0 :(得分:0)
您的代码接近您想要的,但是:
由于网格非常大,printGrid()
如何知道大小?您也应该将大小作为参数传递。
不要两次创建Coord
对象。只创建一次并分配给变量,因此可以使用两次
这一点被下一个子弹否定了,但是做得好,对吗?
请勿致电containsKey()
,然后致电get()
。由于您的地图不会有空值(根据您使用它的方式),get()
返回的空值足以存在测试。
不要在循环中执行string += string
。使用StringBuilder
。当字符串变大时,性能差异很大。
因此,您的代码变为:
public static String printGrid(HashMap<Coord, Integer> map, int width, int height) {
StringBuilder grid = new StringBuilder(height * (width + 1)); // Pre-sizing is optional, but
// may improve performance a bit
for (int row = 0; row < height; row++) {
for (int column = 0; column < width; column++) {
Integer value = map.get(new Coord(column, row));
if (value != null) {
grid.append(value);
} else {
grid.append('#');
}
}
grid.append('\n'); // next row
}
return grid.toString();
}
答案 1 :(得分:0)
考虑到安德烈亚斯的建议,这是我的主张
在 Coord 类
中添加 int neighborsstatic class Coord {
int x;
int y;
int neighbours;
public Coord(int x, int y) {
this(x, y, 0);
}
public Coord(int x, int y, int neighbours) {
this.x = x;
this.y = y;
this.neighbours = neighbours;
}
// getters and setters here
// Equals method here
}
添加一个从坐标
中检索Coord对象的方法Coord getCoord(HashSet<Coord> data, int x, int y) {
Coord coord = new Coord(x, y);
if (data.contains(coord)) {
for (Coord c : data) {
if (c.equals(coord)){
return c;
}
}
}
return null;
}
您的 printGrid 方法将如下
String printGrid(HashSet<Coord> data, int width, int height) {
StringBuilder grid = new StringBuilder(height * (width + 1));
Coord coord;
for (int row = 0; row < height; row++) {
for (int column = 0; column < width; column++) {
coord = getCoord(data, row, column);
if(coord != null) {
grid.append(coord.getNeighbours());
} else {
grid.append('#');
}
}
grid.append('\n'); // next row
}
return grid.toString();
}
在您的主方法中,您将拥有此
HashSet<Coord> data = new HashSet<>();
data.add(new Coord(0, 0, 1));
data.add(new Coord(1, 2, 5));
data.add(new Coord(3, 4, 1));
data.add(new Coord(4, 5, 3));
data.add(new Coord(4, 6, 2));
System.out.println(printGrid(data, 10, 10));
你也可以像这样使用 ArrayList
Coord getCoordWithList(ArrayList<Coord> data, int x, int y) {
Coord coord = new Coord(x, y);
int index = data.indexOf(coord);
if (index > -1) {
return data.get(index);
}
return null;
}
答案 2 :(得分:0)
我认为以下代码符合您的要求。基本上您可以创建一个StringBuilder对象并使用所有'#'对其进行初始化。然后,基于地图中的Coord对象,使用map中的值替换构建器中的相应字符。这很简单,您不需要为每个网格单元创建Coord对象。
public static String printGrid(HashMap<Coord, Integer> map) {
int width = 10;
int height = 10;
int lenght = height * width ;
StringBuilder grid = new StringBuilder(lenght);
// Initialize the builder
int i = 0 ;
while(i<lenght){
if(i >= width && i%(width)==0){
grid.append('\n');
}
grid.append('#');
i++;
}
for(Coord c : map.keySet()){
int index = c.x *(width + 1) + c.y;
grid.setCharAt(index, map.get(c).toString().charAt(0));
}
return grid.toString();
}
输出:
1#########
##5#######
##########
####1#####
#####32###
##########
##########
##########
##########
##########
希望这可以提供帮助。
答案 3 :(得分:-1)
除了使用 Coord 对象作为键的映射外,您可以使用String作为键。您的字符串键将是 Coord 的 x 和 y 值的串联。
所以你会有这个
for (int row = 0; row < grid_height; row++) {
for (int column = 0; column < grid_width; column++) {
String key = column + "#" + row;
if(map.containsKey(key)) {
grid += map.get(key) + "";
} else {
grid += "#";
}
}
grid += "\n"; // next row
}
对于地图的初始化,您将拥有此
HashMap<String, Integer> map = new HashMap<String, Integer>();
map.put("0#0", 1);
map.put("1#2", 5);
map.put("3#4", 1);
map.put("4#5", 3);
map.put("4#6", 2);
System.out.println(printGrid(map));
您可以只使用HashSet代替使用HashMap来存储数据。地图的整数值将是 Coord 类的属性