Javaの列挙型(enum)は固定された定数群を表現する強力な仕組みです。しかし、特定のプロパティ値(例:文字列コードや数値ID)から対応する列挙定数を検索したい場合、標準機能だけでは不足します。この要件を満たすための実装手法を紹介します。
実装手順の概要
| ステップ | 内容 |
|---|---|
| 1. 列挙型の定義 | プロパティを持つ列挙型を宣言 |
| 2. コンストラクタの実装 | 各定数にプロパティを紐付ける |
| 3. 検索メソッドの追加 | プロパティ値から定数を探索する静的メソッド |
| 4. キャッシュの導入(オプション) | 頻繁な検索に備えてMapで高速化 |
| 5. 動作確認 | テストケースで検証 |
基本的な実装例
public enum Status {
ACTIVE("active", 1),
INACTIVE("inactive", 0),
PENDING("pending", 2);
private final String code;
private final int id;
Status(String code, int id) {
this.code = code;
this.id = id;
}
public String getCode() { return code; }
public int getId() { return id; }
// 文字列コードから定数を取得
public static Status findByCode(String code) {
for (Status s : values()) {
if (s.code.equals(code)) {
return s;
}
}
throw new IllegalArgumentException("Unknown code: " + code);
}
// 数値IDから定数を取得
public static Status findById(int id) {
for (Status s : values()) {
if (s.id == id) {
return s;
}
}
throw new IllegalArgumentException("Unknown ID: " + id);
}
}
高速化版:静的初期化によるキャッシュ
public enum Priority {
LOW("low", 1),
MEDIUM("medium", 2),
HIGH("high", 3);
private final String label;
private final int level;
private static final Map<String, Priority> BY_LABEL = new HashMap<>();
private static final Map<Integer, Priority> BY_LEVEL = new HashMap<>();
static {
for (Priority p : values()) {
BY_LABEL.put(p.label, p);
BY_LEVEL.put(p.level, p);
}
}
Priority(String label, int level) {
this.label = label;
this.level = level;
}
public static Priority fromLabel(String label) {
Priority p = BY_LABEL.get(label);
if (p == null) throw new IllegalArgumentException("Invalid label: " + label);
return p;
}
public static Priority fromLevel(int level) {
Priority p = BY_LEVEL.get(level);
if (p == null) throw new IllegalArgumentException("Invalid level: " + level);
return p;
}
}
使用例
public class EnumLookupDemo {
public static void main(String[] args) {
// 基本版の使用
Status status1 = Status.findByCode("active");
System.out.println(status1); // ACTIVE
// 高速版の使用
Priority priority = Priority.fromLabel("high");
System.out.println(priority); // HIGH
// 存在しない値の場合は例外が発生
try {
Status invalid = Status.findByCode("unknown");
} catch (IllegalArgumentException e) {
System.out.println("エラー: " + e.getMessage());
}
}
}