Enumを中身から逆引きして取得する

Enumの中身から値を逆引きして取得したい場合に、どのような手法があるかを紹介します。

# ◆手法1 - Enumクラスに取得用のメソッドを作る

__Enumクラス__
例として、メンバ変数にコード値と名称を持ったEnumのクラスを作成します。

```java:SolarSystem.java
import java.util.Arrays;


public enum SolarSystem {

    MERCURY("S01", "水星"),
    VENUS("S02", "金星"),
    EARTH("S03", "地球"),
    MARS("S04", "火星"),
    JUPITER("S05", "木星"),
    SATURN("S06", "土星"),
    URANUS("S07", "天王星"),
    NEPTUNE("S08", "海王星");

    /** コード値 */
    private String code;

    /** 日本語名称 */
    private String jpName;


    SolarSystem(String code, String jpName) {
        this.code = code;
        this.jpName = jpName;
    }


    /**
     * @return コード値
     */
    public String getCode() {
        return code;
    }


    /**
     * @return 日本語名称
     */
    public String getJpName() {
        return jpName;
    }


    /**
     * 日本語名称からEnumを取得する（for文利用）
     *
     * @param code
     * @return
     */
    public static SolarSystem getByCode(String code) {
        for (SolarSystem solorSystem : SolarSystem.values()) {
            if (solorSystem.getCode().equals(code)) {
                return solorSystem;
            }
        }
        return null;
    }


    /**
     * 日本語名称からEnumを取得する（stream利用）
     *
     * @param code
     * @return
     */
    public static SolarSystem getByCode2(String code) {
        return Arrays.stream(SolarSystem.values())
                .filter(data -> data.getCode().equals(code))
                .findFirst()
                .orElse(null);
    }
}
```

__getByCode__ メソッドが逆引きを実施する処理になります。
（getByCode2メソッドもstreamで書き換えているだけで同様の処理になります）


__使用例__

```java
public static void main(String args[]) {

    SolarSystem object = SolarSystem.getByCode("S03");     // object: "EARTH"
    SolarSystem object2 = SolarSystem.getByCode2("S05");   // object2: "JUPITER"
}
```

# ◆手法2 - 逆引き用ユーティリティを作成する。

上記の実装でやりたいことは実現できますが、逆引きをしたいEnumクラスが複数あった場合に一々実装していくのは現実的ではありません。
そこで個別に実装せずに、ユーティリティのような形で取得できるようにします。

__インターフェース作成__
まずは対象となるEnumクラスにimplemetsさせるインターフェースを作成します。
　※この例ではコード値と名称を持つEnumである…と定義しています。

```java:CodeInterface.java
public interface CodeInterface {

    public String getCode();

    public String getJpName();

}
```

__Enumクラス__
上記インターフェースを実装したEnumを作成します

```java:SolarSystem.java
public enum SolarSystem implements CodeInterface {

    MERCURY("S01", "水星"),
    VENUS("S02", "金星"),
    EARTH("S03", "地球"),
    MARS("S04", "火星"),
    JUPITER("S05", "木星"),
    SATURN("S06", "土星"),
    URANUS("S07", "天王星"),
    NEPTUNE("S08", "海王星");


    /** コード値 */
    private String code;

    /** 日本語名称 */
    private String jpName;


    SolarSystem(String code, String jpName) {
        this.code = code;
        this.jpName = jpName;
    }


    /**
     * @return コード値
     */
    @Override
    public String getCode() {
        return code;
    }


    /**
     * @return 日本語名称
     */
    @Override
    public String getJpName() {
        return jpName;
    }
}
```

__ユーティリティのクラス・メソッド__
逆引き処理を実行するstaticメソッドを作成。

```java:EnumUtils.java
import java.util.Arrays;

public class EnumUtils {


    /**
     * 第一引数に指定されたEnumの中から、第2引数のコード値と一致するものを取得する。
     *
     * @param target 取得したいEnumのクラス
     * @param code   検索するコード値
     * @param <E>    CodeInterfaceを実装したEnumクラス
     * @return
     */
    public static <E extends Enum & CodeInterface> E valueOf(Class<E> target, String code) {

        return Arrays.stream(target.getEnumConstants())
                .filter(data -> data.getCode().equals(code))
                .findFirst()
                .orElse(null);
    }
}
```

__使用例__

```java:
public static void main(String args[]) {

    SolarSystem object = EnumUtils.valueOf(SolarSystem.class, "S02");   // object: "VENUS"
}
```