如何组合并返回枚举值

时间:2015-06-20 22:07:14

标签: 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) {
        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;
}

那么我可以尝试一种更有效的方法吗?

3 个答案:

答案 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>>保留xy作为索引的位置。计算新的xy后,获取Direction就像matrix.get(x).get(y)一样简单。