【Java】型安全な(Map|List)リテラルのようなものを実装してみた
Javaを書いてて、
|
|
みたいなのを沢山書くのが超絶面倒だったので作っちゃいました。
Mapリテラル
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package literal; | |
import java.util.LinkedHashMap; | |
import java.util.Map; | |
public class M { | |
private M(){} | |
public static <K, V> MapBuilder<K, V> put(K key, V value) { | |
MapBuilder<K, V> mapBuilder = new MapBuilder<K, V>(); | |
return mapBuilder.put(key, value); | |
} | |
public static class MapBuilder<K, V> { | |
private MapBuilder(){}; | |
private Map<K, V> map = new LinkedHashMap<K, V>(); | |
public MapBuilder<K, V> put(K key, V value) { | |
map.put(key, value); | |
return this; | |
} | |
public Map<K, V> end() { | |
return map; | |
} | |
} | |
} |
|
|
実装について
Builderパターン(の変形)を使ってMapを生成しているだけです。ただ、可読性を高めるために以下の仕掛けを施しています
- 「put(K key, V value)」メソッドでBuilderのオブジェクトを生成し、さらに同名の「put(K key, V value)」メソッドで値追加をすることでIDE(というより自分)を騙す。
- Builderクラスに渡される型パラメータ(KとV)は、オブジェクト生成時(つまり、1回目のput時)に確定します。なので、代入先のMapと同じ型だけをputできます。キャスト不要で型安全。
- 普通は「build()」とか「construct()」とかにするところを「end()」にして終わった感を出す。
たとえば、
|
|
みたいなコードはコンパイルエラーになります。素敵。
Listリテラル
同様にListリテラルも作ってみました。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package literal; | |
import java.util.ArrayList; | |
import java.util.List; | |
public class L { | |
private L(){} | |
public static <T> ListBuilder<T> add(T e) { | |
ListBuilder<T> listBuilder = new ListBuilder<T>(); | |
return listBuilder.add(e); | |
} | |
public static class ListBuilder<T> { | |
private ListBuilder(){}; | |
private List<T> list = new ArrayList<T>(); | |
public ListBuilder<T> add(T e) { | |
list.add(e); | |
return this; | |
} | |
public List<T> end() { | |
return list; | |
} | |
} | |
} |
|
|
仕組みはMapのときと同じなので説明は割愛。
まとめ
え? リテラルじゃないって?楽できて見やすいからいーのです。