EnumMap / EnumSet の活用(enum 最適化) — 小さい高速マップ/集合
Java には「列挙型(enum)」専用に最適化されたコレクションが用意されています。
それが EnumMap と EnumSet。通常の HashMap や HashSet よりも 軽量・高速 に動作します。初心者向けに、例題を交えて解説します。
EnumMap の特徴
- キーが enum 専用: 他の型は使えない。
- 内部は配列で管理: ハッシュ計算不要 → 高速。
- メモリ効率が良い: 小さいマップに最適。
- 用途: 「enum をキーにした設定表」「状態管理」。
基本コード例
import java.util.EnumMap;
enum Day { MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY }
public class EnumMapDemo {
public static void main(String[] args) {
EnumMap<Day, String> schedule = new EnumMap<>(Day.class);
schedule.put(Day.MONDAY, "Meeting");
schedule.put(Day.WEDNESDAY, "Workshop");
schedule.put(Day.FRIDAY, "Presentation");
System.out.println(schedule);
// {MONDAY=Meeting, WEDNESDAY=Workshop, FRIDAY=Presentation}
}
}
Java👉 ポイント:
- キーは必ず enum。
- 出力は enum の定義順で並ぶ。
EnumSet の特徴
- 要素が enum 専用: 他の型は使えない。
- 内部はビットフラグ: 高速でメモリ効率が良い。
- 順序は enum 定義順。
- 用途: 「enum の集合」「複数状態の管理」。
基本コード例
import java.util.EnumSet;
enum Permission { READ, WRITE, EXECUTE }
public class EnumSetDemo {
public static void main(String[] args) {
EnumSet<Permission> perms = EnumSet.of(Permission.READ, Permission.WRITE);
System.out.println(perms); // [READ, WRITE]
perms.add(Permission.EXECUTE);
System.out.println(perms); // [READ, WRITE, EXECUTE]
perms.remove(Permission.WRITE);
System.out.println(perms); // [READ, EXECUTE]
}
}
Java👉 ポイント:
EnumSet.of(...)で初期化。- 集合演算が高速。
性能の考え方
| コレクション | 特徴 | 適用場面 |
|---|---|---|
| HashMap/HashSet | 汎用的、キー/要素は何でもOK | 大規模・汎用用途 |
| EnumMap | enumキー専用、配列ベースで高速 | 状態表、enum→値の対応 |
| EnumSet | enum要素専用、ビットベースで高速 | 権限管理、複数状態の保持 |
👉 まとめ: enum をキーや要素に使うなら、EnumMap/EnumSet が最適。
例題で練習
例題1: 曜日ごとの営業時間(EnumMap)
EnumMap<Day, String> hours = new EnumMap<>(Day.class);
hours.put(Day.MONDAY, "9:00-17:00");
hours.put(Day.SATURDAY, "10:00-14:00");
System.out.println(hours.get(Day.MONDAY)); // 9:00-17:00
Java例題2: ユーザー権限管理(EnumSet)
EnumSet<Permission> userPerms = EnumSet.noneOf(Permission.class);
userPerms.add(Permission.READ);
userPerms.add(Permission.WRITE);
System.out.println(userPerms.contains(Permission.EXECUTE)); // false
Java例題3: 全要素操作
EnumSet<Permission> all = EnumSet.allOf(Permission.class); // 全権限
EnumSet<Permission> none = EnumSet.noneOf(Permission.class); // 空集合
Javaテンプレート集
EnumMap
EnumMap<EnumType, ValueType> map = new EnumMap<>(EnumType.class);
map.put(EnumType.VALUE, someValue);
ValueType v = map.get(EnumType.VALUE);
JavaEnumSet
EnumSet<EnumType> set = EnumSet.of(EnumType.VALUE1, EnumType.VALUE2);
set.add(EnumType.VALUE3);
set.remove(EnumType.VALUE1);
boolean exists = set.contains(EnumType.VALUE2);
Java実務でのコツ
- 状態管理: EnumMap で「状態→処理内容」を対応付ける。
- 権限管理: EnumSet で「複数権限」をまとめて扱う。
- 高速・省メモリ: 小規模で頻繁にアクセスする用途に最適。
- 順序保持: 出力は enum 定義順なので見やすい。
まとめ
- EnumMap: enum をキーにした高速マップ。
- EnumSet: enum を要素にした高速集合。
- 用途: 状態表、権限管理、複数状態の保持。
👉 練習課題として「ユーザー権限を EnumSet で管理し、EnumMap で権限ごとの説明文を保持する」プログラムを書いてみると、両者の便利さが体感できます。
