JavaでMap
のキーにenum
を使いたいとき、HashMap
で済ませていませんか?
確かにHashMap
でも動作しますが、実はその選択はパフォーマンスやメンテナンス性に悪影響を与えているかもしれません。
本記事では、なぜEnumMap
を使うべきなのか、その理由と使いどころを詳しく解説します。
目次
EnumMapとは?
EnumMap
は、Java標準ライブラリに含まれるMap
の実装の一つで、キーにenum
型を使うことを前提として設計された特殊なMapです。
Map<DayOfWeek, String> schedule = new EnumMap<>(DayOfWeek.class);
このように、EnumMap
はキーとなるenum
型を指定して生成します。
内部構造は配列ベース
であり、enum.ordinal()
を使って要素に高速アクセスするため、非常に効率的です。
なぜEnumMapを使うべきなのか?
✅ 1. 高速なパフォーマンス
EnumMap
は、ハッシュ計算を行わず、enum.ordinal()
を使って配列インデックスに直接アクセスします。
そのため、HashMap
よりも圧倒的に高速です。
✅ 2. メモリ効率が良い
内部が固定サイズの配列なので、オブジェクトの割り当てが最小限で済みます。
GC負荷も低く、サーバーアプリケーションなどで恩恵を受けやすいです。
✅ 3. 型安全で可読性が高い
EnumMap<Status, String>
と明示することで、設計の意図が明確になり、コードの可読性と保守性が向上します。
HashMapとの比較
項目 | EnumMap | HashMap |
---|---|---|
キーの型 | enum 専用 | 任意のオブジェクト |
内部構造 | 配列(ordinalによるアクセス) | ハッシュテーブル |
パフォーマンス | 非常に高速 | 比較的遅い(enumには過剰) |
メモリ効率 | 高い | 標準的 |
nullキー | 許容しない | 許容する |
サンプルコードでEnumMapを使ってみよう
以下は、曜日ごとの予定を保持するシンプルな例です。
import java.util.EnumMap;
import java.util.Map;
import java.util.Map.Entry;
enum Day {
MONDAY, TUESDAY, WEDNESDAY
}
public class EnumMapExample {
public static void main(String[] args) {
Map<Day, String> schedule = new EnumMap<>(Day.class);
schedule.put(Day.MONDAY, "会議");
schedule.put(Day.TUESDAY, "開発");
schedule.put(Day.WEDNESDAY, "レビュー");
for (Entry<Day, String> day : schedule.entrySet()) {
System.out.println(day.getKey() + ": " + day.getValue());
}
}
}
このコードは、enum
の定義順に要素が出力されます。順序が保証されているのもEnumMap
の利点です。
EnumMapを使う際の注意点
null
キーは許されません(NullPointerException
が発生)- キーは
enum
型でなければなりません enum
の定義順(ordinal)に依存するため、定義の変更に注意が必要です
EnumMapを使うべきケース/使わなくてもよいケース
使うべきケース
- キーが限定的かつ列挙可能なとき(状態、曜日、種別など)
- 高速なアクセスが求められる処理
- メモリ効率を重視したいとき
使わなくてよいケース
- キーが動的に変化する場合
- キーにnullを含めたい場合
- 汎用性を求める場合(この場合は
HashMap
が無難)
まとめ
EnumMap
は、「キーにenumを使いたい」というケースにおいて、
高速性・軽量性・可読性のすべてを兼ね備えた最適なMap実装です。
JavaでMap<Enum, V>
のような構造を使う場合、迷わずEnumMap
を選択することで、
パフォーマンスと保守性の両立を実現できます。