具有构造函数的Java枚举。通过构造函数参数获取价值的最佳方法

时间:2019-04-09 11:37:03

标签: java

假设我下面有这个枚举:

public enum RockPaperScissors {
    R("Rock"),
    P("Paper"),
    S("Scissors");

    private final String fullName;

    RockPaperScissors(String fullName) {
        this.fullName = fullName;
    }

    public String getFullName() {
        return fullName;
    }

    public static RockPaperScissors getInstanceByFullName(String fullName) {
        return Arrays.stream(values())
                .filter(value -> value.getFullName().equals(fullName))
                .findFirst().orElseThrow(() -> new IllegalArgumentException("No such value in the enum"));
    }
}

我都想要 RockPaperScissors.valueOf("R")RockPaperScissors.getInstanceByFullName("Paper")之所以能够正常工作,是因为我是由其他数据提供者调用的。

我写的getInstanceByFullName方法还有更好的选择吗?

编辑:我的问题是Java枚举API是否提供了一些替代方法,显然没有。正如ernest_k所建议的,我改进了getInstanceByFullName方法。

3 个答案:

答案 0 :(得分:5)

最简单的解决方案可能是在枚举中维护静态Map<String, RockPaperScissors>

public enum RockPaperScissors {
    R ("Rock"),
    P ("Paper"),
    S ("Scissors");

    private static final Map<String, RockPaperScissors> byFullName = new HashMap<>();
    private final String fullName;

    RockPaperScissors(String fullName) {
        this.fullName = fullName;
        byFullName.put(fullName, this);
    }

    public String getFullName() {
        return fullName;
    }

    public static RockPaperScissors getInstanceByFullName(String fullName) {
        return byFullName.get(fullName);
    }
}

基本上,您只需要在装入枚举类时预先计算Map,即可通过全名进行快速查找。

(实际上,是否比循环遍历所有值要快取决于枚举的大小。仅使用三个元素,循环可能会更快。)

答案 1 :(得分:3)

您只能执行一项流操作:

   public static RockPaperScissors getInstanceByFullName(String fullName) {
        return Arrays.stream(values())
              .filter(rockPaperScissors -> rockPaperScissors.getFullName().equals(fullName))
              .findFirst()
              .orElseThrow(() -> new IllegalArgumentException("No such value in the enum"));
    }

答案 2 :(得分:2)

您可以简化它,而不能两次stream,例如:

public static RockPaperScissors getInstanceByFullName(String fullName) {
    for(RockPaperScissors element : values()) {
        if(element.fullName.equals(fullName)) {
            return element;
        }
    }
    throw new IllegalArgumentException("No such value in the enum");
}