En-04: Enum + Switch 文・Stream API での処理
Enum と Switch 式・Stream API を組み合わせた実用的な処理パターンを解説します。EnumSet やEnumMap を活用すると、 Enum をキーにした処理が HashMap より高速かつ型安全になります。
いつ使うか
- Enum の種類によって処理を分岐させたいとき(switch 式・Stream API)
- Enum の特定の値だけを集めて操作したいとき(EnumSet)
- Enum をキーとしてデータを管理したいとき(EnumMap)
EnumSet・EnumMap のパフォーマンスの特徴
| クラス | 内部実装 | 特徴 |
|---|---|---|
EnumSet | ビットベクトル | HashSet より高速・null 不可 |
EnumMap | 配列(ordinal をインデックスに使用) | HashMap より高速・キーに null 不可 |
サンプルコード
Java 8 では switch 文に break が必要です。case をまとめるには同じ case ラベルを連続して書きます(フォールスルー)。EnumSet・EnumMap は Java 5 から使えますが、Stream API は Java 8 からです。
よくあるミス・注意点
switch 文の break 忘れによるフォールスルー
Java 8 の switch 文では各 case に break が必要です。 break を忘れると次の case の処理も実行されます(フォールスルー)。 Java 14 以降の switch 式(-> 記法)ではフォールスルーが発生しないため、break が不要です。
EnumSet に null を追加すると NullPointerException が発生する
EnumSet とEnumMap はいずれも null キーを許可しません。 null を追加しようとすると NullPointerException がスローされます。 null チェックが必要な場合は通常の HashSet やHashMap を使いましょう。
Arrays.stream(values()) は毎回配列をコピーする
Enum.values() は呼び出すたびに新しい配列を生成します。 ループで繰り返し呼び出す場合はパフォーマンスに影響する可能性があります。 頻繁に参照する場合は static フィールドに保存しておく方法もあります。
switch 式(Java 14+)では全ケースを網羅しないとコンパイルエラー
switch 式で Enum を使う場合、全定数を列挙しないとコンパイルエラーになります。 これは安全性を高める仕組みで、後から Enum に定数を追加したとき、 switch 式を修正し忘れるとコンパイル時に気づけます。
テストする観点
- switch 式で各 Day 定数を渡したとき、期待する文字列("平日" / "休日")が返ること
EnumSet.range(MONDAY, FRIDAY)が MONDAY〜FRIDAY の 5 要素を含むことEnumSet.of(SATURDAY, SUNDAY)が 2 要素を含み、MONDAY を含まないことEnumMapに登録したタスクが Priority の定義順(LOW → CRITICAL)で取得できること- Stream の filter で週末のみを取得したとき、SATURDAY・SUNDAY だけが返ること
isWeekend()が SATURDAY・SUNDAY で true、それ以外で false を返すこと(境界値: FRIDAY・SATURDAY)