Javaで1行でマップを初期化する方法

こんにちは、さるまりんです。

マップの初期化を1行で。以前リストでやりました。それをマップでできないか考えてみました。

コード(code)をキーにそれに対する比率(ratio)を値として持つマップです。

Map<String, Float> codeRatioMap = new HashMap<String, Float>();
codeRatioMap.put("A001", 0.18f);
codeRatioMap.put("A002", 0.23f);
codeRatioMap.put("B003", 0.77f);
codeRatioMap.put("C004", 0.51f);
codeRatioMap.put("C005", 1.05f);

これを1行で書くには初期化ブロックを使います。

Map<String, Float> codeRatioMap = new HashMap<String, Float>(){{
    put("A001", 0.18f);
    put("A002", 0.23f);
    put("B003", 0.77f);
    put("C004", 0.51f);
    put("C005", 1.05f);
}};

1行、1ステートメントになりました。

Streamインターフェースを使うこんな方法もあります。

Map<String, Float> codeRatioMap = Stream.of(new Object[][] {
    {"A001", 0.18f},
    {"A002", 0.23f},
    {"B003", 0.77f},
    {"C004", 0.51f},
    {"C005", 1.05f},
}).collect(Collectors.toMap(data -> (String) data[0], data -> (Float) data[1]));

Map.of()メソッドを使ってこんな風に作ることもできます。

Map<String, Float> codeRatioMap = Map.of(
    "A001", 0.18f,
    "A002", 0.23f,
    "B003", 0.77f,
    "C004", 0.51f,
    "C005", 1.05f
);

この作り方で注意が必要なのは、できたマップが変更不可(immutable)となることです。
なので、これ以降で

codeRatioMap.put("D006", 0.83f);

のようにコードと比率を追加しようとするとUnsupportedOperationExceptionが発生します。

可変(mutable)のマップを作る必要があるのであれば、できた不変のマップをコンストラクタに渡して新しいマップを作ります。

Map<String, Float> codeRatioMap = new HashMap<String, Float>(Map.of(
    "A001", 0.18f,
    "A002", 0.23f,
    "B003", 0.77f,
    "C004", 0.51f,
    "C005", 1.05f
));

Map.of()は追加できるキーと値の組み合わせが10個までという制約があるので、それを超えるときはMap.ofEntries()を使います。

Map<String, Float> codeRatioMap = Map.ofEntries(
    new AbstractMap.SimpleEntry<String, Float>("A001", 0.18f),
    new AbstractMap.SimpleEntry<String, Float>("A002", 0.23f),
    new AbstractMap.SimpleEntry<String, Float>("B003", 0.77f),
    new AbstractMap.SimpleEntry<String, Float>("C004", 0.51f),
    new AbstractMap.SimpleEntry<String, Float>("C005", 1.05f)
);

いろんなやり方がありますね。
「その書き方、長くなりすぎない?」とか気になるところ、好みもあると思います。
その時その時でわかりやすいプログラムを書けるよう、これからも勉強します。

読んでくださってありがとうございます。
それではまた!