115

我想声明一个枚举方向,它有一个返回相反方向的方法(以下语法不正确,即无法实例化枚举,但它说明了我的观点)。这在Java中可能吗?

这是代码:

public enum Direction {

     NORTH(1),
     SOUTH(-1),
     EAST(-2),
     WEST(2);

     Direction(int code){
          this.code=code;
     }
     protected int code;
     public int getCode() {
           return this.code;
     }
     static Direction getOppositeDirection(Direction d){
           return new Direction(d.getCode() * -1);
     }
}
4

6 回答 6

216

对于那些被标题吸引的人:是的,您可以在枚举中定义自己的方法。如果您想知道如何调用此类非静态方法,您可以像使用任何其他非静态方法一样执行此操作 - 您可以在定义或继承该方法的类型实例上调用它。在枚举的情况下,此类实例只是ENUM_CONSTANTs。

所以你只需要EnumType.ENUM_CONSTANT.methodName(arguments).


现在让我们从问题回到问题。解决方案之一可能是

public enum Direction {

    NORTH, SOUTH, EAST, WEST;

    private Direction opposite;

    static {
        NORTH.opposite = SOUTH;
        SOUTH.opposite = NORTH;
        EAST.opposite = WEST;
        WEST.opposite = EAST;
    }

    public Direction getOppositeDirection() {
        return opposite;
    }

}

现在Direction.NORTH.getOppositeDirection()将返回Direction.SOUTH


这是说明@jedwards评论的更“hacky”方式,但它不像第一种方法那样灵活,因为添加更多字段或更改它们的顺序会破坏我们的代码。

public enum Direction {
    NORTH, EAST, SOUTH, WEST;

    // cached values to avoid recreating such array each time method is called
    private static final Direction[] VALUES = values();

    public Direction getOppositeDirection() {
        return VALUES[(ordinal() + 2) % 4]; 
    }
}
于 2013-09-18T23:01:25.517 回答
164

对于像这样的小枚举,我发现最易读的解决方案是:

public enum Direction {

    NORTH {
        @Override
        public Direction getOppositeDirection() {
            return SOUTH;
        }
    }, 
    SOUTH {
        @Override
        public Direction getOppositeDirection() {
            return NORTH;
        }
    },
    EAST {
        @Override
        public Direction getOppositeDirection() {
            return WEST;
        }
    },
    WEST {
        @Override
        public Direction getOppositeDirection() {
            return EAST;
        }
    };


    public abstract Direction getOppositeDirection();

}
于 2013-09-18T23:06:24.080 回答
29

这有效:

public enum Direction {
    NORTH, SOUTH, EAST, WEST;

    public Direction oppose() {
        switch(this) {
            case NORTH: return SOUTH;
            case SOUTH: return NORTH;
            case EAST:  return WEST;
            case WEST:  return EAST;
        }
        throw new RuntimeException("Case not implemented");
    }
}
于 2014-11-19T17:50:10.343 回答
15

创建一个抽象方法,并让每个枚举值覆盖它。由于您在创建它时知道相反的情况,因此无需动态生成或创建它。

虽然它读起来不太好。也许 aswitch会更易于管理?

public enum Direction {
    NORTH(1) {
        @Override
        public Direction getOppositeDirection() {
            return Direction.SOUTH;
        }
    },
    SOUTH(-1) {
        @Override
        public Direction getOppositeDirection() {
            return Direction.NORTH;
        }
    },
    EAST(-2) {
        @Override
        public Direction getOppositeDirection() {
            return Direction.WEST;
        }
    },
    WEST(2) {
        @Override
        public Direction getOppositeDirection() {
            return Direction.EAST;
        }
    };

    Direction(int code){
        this.code=code;
    }
    protected int code;

    public int getCode() {
        return this.code;
    }

    public abstract Direction getOppositeDirection();
}
于 2013-09-18T23:04:11.877 回答
4

是的,我们一直这样做。您返回一个静态实例而不是一个新对象

 static Direction getOppositeDirection(Direction d){
       Direction result = null;
       if (d != null){
           int newCode = -d.getCode();
           for (Direction direction : Direction.values()){
               if (d.getCode() == newCode){
                   result = direction;
               }
           }
       }
       return result;
 }
于 2013-09-18T23:00:05.507 回答
0
public enum Direction {
    NORTH, EAST, SOUTH, WEST;

    public Direction getOppositeDirection(){
        return Direction.values()[(this.ordinal() + 2) % 4];
    }
}

枚举有一个静态值方法,该方法返回一个数组,该数组按照声明的顺序包含枚举的所有值。资源

因为 NORTH 得到 1,EAST 得到 2,SOUTH 得到 3,WEST 得到 4;您可以创建一个简单的方程式来获得相反的方程式:

(值 + 2) % 4

于 2017-06-26T19:48:16.290 回答