くんすとの備忘録

IT系技術メモ

移転しました。

15秒後に自動的にリダイレクトします。

【Java】型安全な(Map|List)リテラルのようなものを実装してみた

Javaを書いてて、

Map<String, String> hogehogeMap = new HashMap<String,String>();
hogehogeMap .put("hoge", "fuga");
hogehogeMap .put("hoehoe", "fugafuga");

みたいなのを沢山書くのが超絶面倒だったので作っちゃいました。

Mapリテラル

お好きなパッケージ(自分は「literal」にしてみました)に突っ込んで、以下のように使います。

Map<String,String> h = literal.M
	.put("1", "fugafuga")
	.put("2", "aaaa")
	.end();

実装について

Builderパターン(の変形)を使ってMapを生成しているだけです。

ただ、可読性を高めるために以下の仕掛けを施しています

  • 「put(K key, V value)」メソッドでBuilderのオブジェクトを生成し、さらに同名の「put(K key, V value)」メソッドで値追加をすることでIDE(というより自分)を騙す。
  • Builderクラスに渡される型パラメータ(KとV)は、オブジェクト生成時(つまり、1回目のput時)に確定します。なので、代入先のMapと同じ型だけをputできます。キャスト不要で型安全。
  • 普通は「build()」とか「construct()」とかにするところを「end()」にして終わった感を出す。

ちゃんとジェネリッククラスで作成しているので、型安全です。
たとえば、

Map<String,String> h = literal.M
	.put(1, "fugafuga")
	.put("2", 2)
	.end();

Map<Integer,String> h = literal.M
	.put("1", "fugafuga")
	.put("2", "2")
	.end();

みたいなコードはコンパイルエラーになります。素敵。

Listリテラル

同様にListリテラルも作ってみました。

使い方は同じで、こんな風にします。

List<String> l = literal.L
	.add("1")
	.add("fuga")
	.add("aa")
	.end();

仕組みはMapのときと同じなので説明は割愛。

まとめ

え? リテラルじゃないって?

楽できて見やすいからいーのです。