我有一个如下的坐标系:
public enum Direction {
N ( 0, 1),
NE ( 1, 1),
E ( 1, 0),
SE ( 1, -1),
S ( 0, -1),
SW (-1, -1),
W (-1, 0),
NW (-1, 1);
private int x = 0, y = 0;
private Direction(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public Direction combine(Direction direction) {
//unsure
}
}
我试图将方向与枚举中的方法结合起来,例如:
Direction.N.combine(Direction.E) -> should become Direction.NE
Direction.N.combine(Direction.N) -> null or Direction.N again
我的想法是遍历枚举中的所有值,并找到一个与其x和y相匹配的值:
public Direction combine(Direction direction) {
Direction[] directions = Direction.values();
for (int i = 0; i < directions.length; i++)
if (x + direction.x == directions[i].x && y + direction.y == directions[i].y)
return directions[i];
return this;
}
但我觉得这是一种低效的方法。还有另一种方法可以将这些方向结合起来并不涉及遍历所有枚举吗?
我还想创建一个非组合函数来反转组合。
Direction.NE.uncombine() -> Direction[] {Direction.N, Direction.E}
我也可以使用相同的循环技术,例如:
public Direction[] uncombine() {
Direction[] directions = Direction.values(),
rtn = new Direction[2];
for (int i = 0; i < directions.length; i++)
if (x == directions[i].x && directions[i].y == 0)
rtn[0] = directions[i];
for (int i = 0; i < directions.length; i++)
if (y == directions[i].y && directions[i].x == 0)
rtn[1] = directions[i];
return rtn;
}
那么我可以尝试一种更有效的方法吗?
答案 0 :(得分:2)
我认为为每个枚举值创建一个Map<Direction, Direction>
可以在性能和代码整洁性之间取得良好的平衡。
combine
方法变为:
public Direction combine(Direction other) {
return this.combinerMap.get(other);
}
当然,您需要在枚举类的初始化期间构建映射。
从此方法返回null
是一个坏主意,因为它将完整性检查的责任推回到调用方。所以我这样写:
public Direction combine(Direction other)
throws InsaneDirectionsException{
Direction res = this.combineMap.get(other);
if (res == null) {
throw new InsaneDirectionsException(
"Can't combine directions " + this +
" and " + other);
}
return res;
}
答案 1 :(得分:1)
如果你的真实课程就像问题那样简单,我认为最有效的方法是手动“硬编码”或预先计算(例如在静态初始化块中)参数和结果之间的关系并保持它在地图中,然后只引用已有的结果。
答案 2 :(得分:0)
您可以Map<Byte, Map<Byte, Direction>>
保留x
和y
作为索引的位置。计算新的x
和y
后,获取Direction
就像matrix.get(x).get(y)
一样简单。