読者です 読者をやめる 読者になる 読者になる

Java で Map リテラル (もどき)

上のは冗談ですが、こっちは割と本気です。
コレクションのリテラルについては
コレクション (List, Set, Map 等) の生成の簡略化 - ぐるぐる~
とかで言及しているんですけど*1、Map については「これだ!」というものがありませんでした。
ですが、最近自分の中では答えが出ました。

public abstract class MapL<K, V> extends LinkedHashMap<K, V> {
    protected void _(K key, V value) { put(key, value); }
}

こんなクラスを用意して、こう使います。

Map<Integer, String> m = new MapL<Integer, String>() {{ _(1, "hoge"); _(5; "piyo"); }};

ほんの少しだけ面倒ですけど、分かりやすい表記に思えなくもないです。
今気付いたんですが、F# の

let m = Map.ofList [(1, "hoge"); (5, "piyo")]

と微妙に似ていますね。だからどうだという話ではないですが。


で、これだと LinkedHashMap、HashMap、Map あたりにしか使えないので、実際には

public abstract class MapL<K, V> extends LinkedHashMap<K, V> {
    protected void _(K key, V value) { put(key, value); }

    public HashMap<K, V> toHashMap() {
        return new HashMap<K, V>(this);
    }

    public LinkedHashMap<K, V> toLinkedHashMap() {
        return new LinkedHashMap<K, V>(this);
    }

    public TreeMap<K, V> toTreeMap() {
        return new TreeMap<K, V>(this);
    }

    public TreeMap<K, V> toTreeMap(Comparator<? super K> comparator) {
        TreeMap<K, V> m = new TreeMap<K, V>(comparator);
        m.putAll(this);
        return m;
    }

    public ConcurrentHashMap<K, V> toConcurrentHashMap() {
        return new ConcurrentHashMap<K, V>(this);
    }

    public ConcurrentSkipListMap<K, V> toConcurrentSkipListMap() {
        return new ConcurrentSkipListMap<K, V>(this);
    }

    public ConcurrentSkipListMap<K, V> toConcurrentSkipListMap(Comparator<? super K> comparator) {
        ConcurrentSkipListMap<K, V> m = new ConcurrentSkipListMap<K, V>(comparator);
        m.putAll(this);
        return m;
    }
}

こんな感じでどうでしょうか。
toString や equals や hashCode をオーバーライドするのもアリかもしれませんね!

TreeMap<Integer, Integer> m = new MapL<Integer, Integer>() {{ _(1, 2); _(3, 4) }}.toTreeMap();

*1:これ、今見るとどこの Scala? って感じですね。