Java 如何组合并返回枚举值

Java 如何组合并返回枚举值,java,enums,Java,Enums,我有这样一个坐标系: 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) { t

我有这样一个坐标系:

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;
}
我也可以使用同样的循环技术,比如:

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;
}
public Direction[]取消组合(){
方向[]方向=方向。值(),
rtn=新方向[2];
对于(int i=0;i

那么有没有一种更有效的方法可以尝试呢?

我认为为每个枚举值创建一个
映射将在性能和代码整洁性之间取得很好的平衡

combine
方法变为:

    public Direction combine(Direction other) {
        return this.combinerMap.get(other);
    }
当然,您需要在enum类初始化期间构建映射

从这个方法返回
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;
    }

您可以保留
Map
,其中
x
y
将作为索引。一旦你计算了新的
x
y
,获得
方向将像
矩阵一样简单。get(x)。get(y)
,如果你的实际类与问题中的类一样简单,我认为最有效的方法是手动“硬编码”或预计算(例如在静态初始化块中)参数和结果之间的关系,并将其保留在映射中,然后仅引用已有的结果。

您能告诉我们,对于Direction.NE.combine(Direction.W)Direction.N.combine(Direction.S)等情况,您希望得到什么样的结果吗?请注意,您的技术是错误的:将N与SE组合会得到E。如果您尝试将N与S组合,您希望返回值是什么?我认为您最好将方向存储为从0到360的浮点度,并具有一个从度转换为最近命名方向的函数。最后,我使用hashmap来正确映射所有坐标之间的关系。
    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;
    }