Javaのバージョン

Java9以降。

immutableなMapを1文でMapを初期化する

Map.ofまたはMap.ofEntriesを使用する。

Map<String, String> map = Map.of(
    "key1", "value1",
    "key2", "value2",
    "key3", "value3"
);
Map<String, String> map = Map.ofEntries(
    Map.entry("key1", "value1"),
    Map.entry("key2", "value2"),
    Map.entry("key3", "value3")
);

entryメソッドをstatic importすれば以下のように記述できる。

import static java.util.Map.entry;

...

Map<String, String> map = Map.ofEntries(
    entry("key1", "value1"),
    entry("key2", "value2"),
    entry("key3", "value3")
);

実行例

import java.util.Map;
import static java.util.Map.entry;

public class Main {
    public static void main(String[] args) {
        // Map.of()でMapを作成
        Map<String, String> map1 = Map.of(
            "key1", "value1",
            "key2", "value2",
            "key3", "value3"
        );
        System.out.println(map1);

        // Map.ofEntries()でMapを作成
        Map<String, String> map1 = Map.ofEntries(
            entry("key1", "value1"),
            entry("key2", "value2"),
            entry("key3", "value3")
        );
        System.out.println(map2);
    }
}
$ javac Main.java
$ java Main
{key1=value1, key2=value2, key3=value3}
{key1=value1, key2=value2, key3=value3}

Map.ofとMap.ofEntriesの違い

Map.ofで作成できるエントリー数は最大10個

Map.ofは最大10個のエントリーを持つMapを作成できる。
11個を超えるとコンパイルエラーとなる。

例えば以下の様なコードの場合。

Map<String, String> map1 = Map.of(
    "key1", "value1",
    "key2", "value2",
    "key3", "value3",
    "key4", "value4",
    "key5", "value5",
    "key6", "value6",
    "key7", "value7",
    "key8", "value8",
    "key9", "value9",
    "key10", "value10",
    "key11", "value11"
);

上記のコードは以下のコンパイルエラーが発生する。

error: no suitable method found for of(String,String,String,String,String,String,String,String,String,String,String,String,String,String,String,String,String,String,String,String,String,String)
Map<String, String> map1 = Map.of(

Map.ofは可変引数で定義されていないらしい。

Map.ofの引数はキーとバリューがどちらか分かりづらい

Map.ofの引数は奇数番目がキー、偶数番目がバリューとなる。
ぱっと見ではどちらがキーでどちらがバリューか分かりづらい。

一方、Map.ofEntriesの引数はMap.entryでくくられるのでどちらがキーでどちらがバリューか分かりやすい。

Map.of("a", "b", "c", "d", "e", "f");
Map.ofEntries(entry("a", "b"), entry("c", "d"), entry("e", "f"));

mutableなMapを1文でMapを初期化する(immutableなMapをHashMap, LinkedHashMapでラップ)

Map.ofまたはMap.ofEntriesで作成したimmutableなMapをHashMapLinkedHashMapに変換すればmutableなMapを1文で作成できる。

import java.util.Map;
import java.util.HashMap;
import java.util.LinkedHashMap;
import static java.util.Map.entry;

public class Main {
    public static void main(String[] args) {
        Map<String, String> map = new LinkedHashMap<>(
            Map.ofEntries(
                entry("key1", "value1"),
                entry("key2", "value2"),
                entry("key3", "value3")
            )
        );
        System.out.println(map);

        map.put("key4", "value4");
        System.out.println(map);
    }
}
$ javac Main.java
$ java Main
{key1=value1, key2=value2, key3=value3}
{key1=value1, key2=value2, key3=value3, key4=value4}

Java 8でも1文でMapを初期化したい(初期化ブロックを使う方法)

Map.ofMap.ofEntriesはJava 9で導入されているためJava 8では使えない。 Java 8でも1文でMapを初期化したい場合、LinkedHashMapnewするときに初期化ブロックを使うと同様なMapを作成できる。

import java.util.Map;
import java.util.LinkedHashMap;

public class Main {
    public static void main(String[] args) {
        Map<String, String> map = new LinkedHashMap<>() {
              {
                    put("key1", "value1");
                    put("key2", "value2");
                    put("key3", "value3");
              }
        };
        System.out.println(map);

        map.put("key4", "value4");
        System.out.println(map);
    }
}
$ javac Main.java
$ java Main
{key1=value1, key2=value2, key3=value3}
{key1=value1, key2=value2, key3=value3, key4=value4}