Javaでデータの入ったMapをクールに初期化する方法

Javaできちんとしたオブジェクト指向のプログラムを記述できる人間は、HashMapなどの、Mapオブジェクトを多用するようになると思う。

例えば、よくあるのが、数値から文字列に変換するときのMapの使用。

2という数値から”second”を取得するというようなときに、Mapはすごく便利。

 

本題に入る前に、私の職場の話。

みな次のように記述しているが、これではプログラマとして話にならない。

やめてくれ。頼むから。

オブジェクト指向の言語では条件分岐はあまり多様してほしくない。

クールにMapを初期化する方法

ここからが本題。

データの入ったMapをクールに初期化する方法がこれだ。

HashMap()コンストラクタ呼び出しの直後に、{{と}}で囲われた部分で内容の初期化をしている。

こうすると、putメソッドの呼び出しも簡潔に呼び出せるだけでなく、orderWordMapは、3つの要素が初めから入ってるものなんだなということがひと目で分かる。

 

でも本当にすごいのはそこではない。

orderWordMap変数をfinal宣言できるというところに注目してほしい。

これで毎回、HashMapをインスタンス化してそこにputするという処理が行われることも無くなり、無駄な処理が無くなる。

 

さらに、orderWordMapは、どのタイミングで実行されても値が固定の変数ということを読み手に伝えることができる。

(プログラムの他の部分でput()やremove()が行われていたら話はその限りではないということになってしまうが)

匿名クラス

先程紹介した、クールにデータの入ったMapを初期化するコードを理解するためには、匿名クラスとインスタンス初期化子について理解しないといけないが、まずは匿名クラスから説明する。

 

オブジェクト指向は、あるクラスを継承してサブクラスを作成することができる。

しかしそのサブクラスを1度しか使用しないことが分かっているような場合には、わざわざサブクラスにクラス名をつける必要性もあまり無い。

 

そんな時に使えるのが、Java言語に実装されている、匿名クラスという仕様だ。

HashMapを継承したサブクラスとして、removeメソッドを呼び出すとUnsupportedOperationException(“removeさせぬよ”)が発生する匿名クラスを作成して、それをインスタンス化していっきにunremovableMapInstance変数に代入している。

 

このように、匿名クラスを使ってサブクラスのインスタンスを作ることで、手軽に一部の機能を書き換えたクラスのインスタンスを作成することができる。

インスタンス初期化子

インスタンス初期化子というのは、引数をとらないコンストラクタのようなものだ。

このように、インスタンス初期化子は、まるでコンストラクタのように使うことができる。

データの入ったMapをクールに初期化した仕組みが見えたと思う

この記事で紹介した、クールにMapを初期化する方法の仕組みは、匿名クラスとインスタンス初期化子を知っていれば、理解できると思う。

おさらいとして、もう一度コードを紹介しながら解説してみよう。

{{と}}の正体は、ただの匿名クラスとインスタンス初期化子の組み合わせに他ならない。

 

気づいているかもしれないが、コンストラクタでなくインスタンス初期化子を使わなければいけない理由は、匿名クラスにはクラス名が無いため、コンストラクタを定義することができないからという、ある意味苦肉の策とも言えなくもないのかもしれない。

“Javaでデータの入ったMapをクールに初期化する方法” への10件のフィードバック

  1. とおりすがり より:

    これクールなの?行数増えてるけど・・・
    あと、値に変数いれれないから、使い道かぎられるね。

  2. ながほげ より:

    とおりすがりさん、こんばんわ。

    せっかくコメント下さったのに、忙しくて気づかず
    さらにインフルエンザでダウンしてて気づきませんでした。

    コメントどうもありがとう(^ω^)

    使い道が限られるからこそ場面によっては読み手に対して明快でよくないですか?

    constやfinalやprivate宣言なんかも、使い道を制限するだけなのに、こういったものって無いと不便ですよね。

    あと、私はたとえ行数が増えても読みやすさのほうを重視します。
    ほとんどの場合、行数が増えるほどに可読性は下がる傾向にありますけど、今回のMapの初期化のようにクールになる(と私は思うがどうか!?)ケースもたまにあります。

  3. ありがとうございます より:

    これを探していました。
    そのものズバリでクールな記法ですね。
    ありがたく使わせて頂きます。

  4. ながほげ より:

    ありがとうございますさん、こんにちわ。

    こういったコメント頂けると、結構うれしいものですね〜。
    精進精進。

  5. t より:

    この場合だと、static initializerのほうが良いかと。

  6. ながほげ より:

    putメソッドはインスタンスメソッドなので、static初期化子の中からは呼び出せないですよ。

  7. Cake より:

    なるほど。すばらしい。

  8. tau より:

    これいいですね。
    美しいです。

  9. Tasker より:

    ハッシュマップせっかく使ってるのに特性をいかさない例をあげてるところが残念。。get(数値)だと配列じゃん、get(“文字列”)で例を出した方が良いと思う。ハッシュマップ作ると意識するんだけどなあ。

  10. s より:

    Mapへの参照はfinalだけどMap自体はいじれるのでは。

コメントを残す

トラックバック: http://pgnote.net/wp-trackback.php?p=32