読者です 読者をやめる 読者になる 読者になる

enum 定数の逆引きは美しくないけどよく使う。。


enumenum 名から取得するのは

public enum Status { RUN, WAIT, READY }

valueOf を使えば良いだけです。

Status.valueOf("RUN");


enum 定数としてコード値などと対応付ける こんな場合、

public enum Status {
    RUN("001"),
    WAIT("010"),
    READY("011"),
    ;
    
    private final String code;
    private Status(final String code) {
        this.code = code;
    }
    public String getCode() { return code; }
}


コード値から Status の emun を取得したいのは良く書くコードですが、逆引きマップを用意しなくてはいけないのはメンドクサイです。しかも美しくないです。。

public enum Status {
  RUN("001"),
  WAIT("010"),
  READY("011"),
  ;
  
  private final String code;
  private Status(final String code) {
      this.code = code;
  }
  public String getCode() { return code; }
  
  public Status codeOf(final String code) {
      return codeToEnum.get(code);
  }
  private static final Map<String, Status> codeToEnum = new HashMap<String, Status>() {{
      for (Status status : Status.values()) put(status.getCode(), status);
  }};
}

codeToEnum マップは private なので イミュータブルにする必要もないでしょう。なるべく短くしたいだけなので、普通に static 初期化ブロツクでも良いです。


コード値の誤った重複追加を防ぐために以下のようにしておくのも良いでしょう。

  private static final Map<String, Status> codeToEnum = new HashMap<String, Status>() {{
      for (Status status : Status.values()) {
          if (put(status.getCode(), status) != null) {
              throw new IllegalArgumentException(status.getCode());
          }
      }
  }};


遅延初期化ホルダーを使うとこんな感じになります。codeOf を使うときに初めてキャッシュされるようになりますが、通常の enum 使う時はやり過ぎなアンチパターンです。

public enum Status {
    RUN("001"),
    WAIT("010"),
    READY("011"),
    ;
    
    private final String code;
    private Status(final String code) {
        this.code = code;
    }
    public String getCode() { return code; }
    
    public Status codeOf(final String code) {
        return LazyInitializHolder.codeToEnum.get(code);
    }
    private static class LazyInitializHolder {
        static final Map<String, Status> codeToEnum = new HashMap<String, Status>() {{
            for (Status status : Status.values()) put(status.getCode(), status);
        }};
    }
}