Effective Javaを読むチャレンジ-項目33 その2-

2つのenum値からの対応付けを表すの序数を使用してインデックスされている配列の配列

とても分かりづらい表現ですが、enumの2次元配列に序数でアクセスするということです。

その例として、相転移のサンプルが載っています。相転移は、ある相(物質のある安定した状態)から別の相へ変えることを言います。例えば相として気体、液体、固体があるとき、相転移として沸騰、凍結、昇華などあります。本書のサンプルは2つの相を相転移に対応付けるために配列の配列を利用しています。

クライアントコードと実行結果です。

上記のように、固体から液体への相転移は「MELT(融解)」と表示されます。

このコードは前回同様、序数を使用した配列へのアクセスによる問題が発生します。そして、例えば相を追加したのに対応する相転移のマッピングを実装し忘れていたとき、ArrayIndexOutBoundsExceptionやNullPointerExceptionなどが発生したり、もっと悪い場合には何も言わずに誤った振る舞いをしたりするかもしれません。

また、相転移の表は相の数の2次だけ必要になるため、該当する相転移がない(nullとなっている箇所)が多くなっても、同じ数だけ表が必要になります。不要なコードが増えるということですね。

そこで、このようなときにもEnumMapが使えますよと続きます。その説明の出だしがこちら。

1つのenum(転移元の相)を、2番目のenum(転移先の相)から結果(相転移)へのマップへマップする関係を表現する方が良い

この表現も本当に分かりづらいですね・・・。本書の後の方で解説してくれていますが、これはMap<転移元enum, Map<転移先enum, 相転移>>という、マップの値にマップを入れた構造のデータを用意すればいいんですよ、という話です。このMapのインスタンスはEnumMapです。

クライアントコードと実行結果は変わりません。このコードでは、相から相への組み合わせごとに対応する相転移を定義するだけで済むので、配列を使用した場合のように不要なコードは生まれません。

そして、定義されていない相から相へのマッピングをクライアントが実行したとき、fromメソッドはnullを返します。ということは、例えば相を追加したあとで必要な相転移の定義を実装し忘れたとすると、クライアントは想定外のnullが戻ってくるので、実装漏れに気付くかもしれません。

序数のインデックスを使用した方が適切だという場面はほぼないので、代わりにEnumMapを使用してくださいということでこの項目は終わりです。

広告
  • LINEで送る