首页 > 解决方案 > 返回相反枚举的优雅方式

问题描述

我有一个枚举,每个元素都有一个相反的元素。我想要一种优雅的方式将它封装在枚举的每个元素中。我的首选选项不合法,因为它使用前向引用。

enum Direction {
    NORTH(SOUTH), SOUTH(NORTH), EAST(WEST), WEST(EAST);

    private final Direction opposite;

    Direction(Direction opposite) {
        this.opposite = opposite;
    }

    public Direction getOpposite() {
        return opposite;
    }
}

使用供应商也是非法的。

enum Direction {
    NORTH(() -> SOUTH), SOUTH(() -> NORTH), EAST(() -> WEST), WEST(() -> EAST);

    private final Supplier<Direction> opposite;

    Direction(Supplier<Direction> opposite) {
        this.opposite = opposite;
    }

    public Direction getOpposite() {
        return opposite.get();
    }
}

这让我不得不重写该方法:

enum Direction {
    NORTH{
        public Direction getOpposite() {
            return SOUTH;
        }
    }, 
    SOUTH{
        public Direction getOpposite() {
            return NORTH;
        }
    }, 
    EAST{
        public Direction getOpposite() {
            return WEST;
        }
    }, 
    WEST{
        public Direction getOpposite() {
            return EAST;
        }
    };

    public abstract Direction getOpposite();
}

使用开关:

enum Direction {
    NORTH, SOUTH, EAST, WEST;

    public Direction getOpposite() {
        return switch(this) {
            case NORTH -> SOUTH;
            case SOUTH -> NORTH;
            case EAST -> WEST;
            case WEST -> EAST;
        }
    }
}

或者地图:

enum Direction {
    NORTH, SOUTH, EAST, WEST;

    private static final Map<Direction,Direction> OPPOSITES =
        Map.of(NORTH, SOUTH, SOUTH, NORTH, EAST, WEST, WEST, EAST);

    public Direction getOpposite() {
        OPPOSITES.get(this);
    }
}

没有任何一种选择像仅仅列出相反的论点那样简单易读。

有没有一种优雅的方法来避免前向引用问题?

标签: javaenums

解决方案


我建议你改变顺序:

enum Direction {
    NORTH, EAST, WEST, SOUTH:
    ...
}

并使用Direction.values()

public Direction opposite() {
    Direction[] array = values();

    return array[(ordinal() + 2) % array.length];
}

推荐阅读