HashMapを直接(リテラルに)初期化する方法は?

JavaのHashMapをこのように初期化する方法はあるのでしょうか。

Map<String,String> test = 
    new HashMap<String, String>{"test":"test","test":"test"};

正しい構文とはどのようなものでしょうか?これに関するものは見つかりませんでした。このようなことは可能でしょうか?私は、マップの作成時にあらかじめ知っている、決して変化しないいくつかの "final/static" 値をマップに入れるための最短/最速の方法を探しています。

質問へのコメント (7)
ソリューション

Java Version 9以上の場合。

はい、これはもう可能です。Java 9では、マップの作成を簡単にするファクトリーメソッドがいくつか追加されました。

// this works for up to 10 elements:
Map test1 = Map.of(
    "a", "b",
    "c", "d"
);

// this works for any number of elements:
Map test2 = Map.ofEntries(
    entry("a", "b"),
    entry("c", "d")
);

上記の例では、testtest2の両方が同じになり、Mapの表現方法が異なるだけである。Map.ofメソッドはマップの要素を10個までと定義されているが、Map.ofEntries`メソッドにはそのような制限はないだろう。

この場合、結果のマップはイミュータブルマップになることに注意してください。もしマップをミュータブルにしたい場合は、例えばmutableMap = new HashMap(Map.of("a", "b"));を用いて再度コピーします。

(JEP 269](http://openjdk.java.net/jeps/269) と Javadoc も参照)。

Java Version 8 までの場合。

いいえ、すべての要素を手動で追加する必要があります。匿名サブクラスでイニシャライザーを使用すると、構文を少し短くすることができます。

Map myMap = new HashMap() {{
        put("a", "b");
        put("c", "d");
    }};

しかし、匿名サブクラスは、場合によっては不要な動作を引き起こす可能性があります。これには例えば

  • メモリ消費量、ディスク消費量、起動時間を増加させる追加クラスを生成します。
  • 非静的メソッドの場合。作成メソッドが呼び出されたオブジェクトへの参照を保持します。つまり、作成されたマップオブジェクトが参照されている間は、外側のクラスのオブジェクトをガベージコレクションすることができないため、追加のメモリをブロックすることができます。

初期化に関数を使うと、イニシャライザでマップを生成することも可能になりますが、厄介な副作用を避けることができます。

Map myMap = createMap();

private static Map createMap() {
    Map myMap = new HashMap();
    myMap.put("a", "b");
    myMap.put("c", "d");
    return myMap;
}
解説 (13)

これは一つの方法です。

HashMap h = new HashMap() {{
    put("a","b");
}};

しかし、注意しなければならないのは、上記のコード(HashMapを継承した新しいクラスを作成している)をしっかりと理解することです。したがって、ここで詳細を読んでおく必要があります。 http://www.c2.com/cgi/wiki?DoubleBraceInitialization または、単にGuavaを使用する。

Map left = ImmutableMap.of("a", 1, "b", 2, "c", 3);
解説 (13)

サードパーティのライブラリを許可する場合は、GuavaImmutableMapを使用して、文字通りのような簡潔さを実現できます。

Map test = ImmutableMap.of("k1", "v1", "k2", "v2");

これは最大5キー/値ペアで機能します。それ以外の場合は、ビルダー:を使用できます。

Map test = ImmutableMap.builder()
    .put("k1", "v1")
    .put("k2", "v2")
    ...
    .build();
< br />。

-GuavaのImmutableMap実装はJavaのHashMap実装とは異なることに注意してください(特に、不変であり、nullキー/値を許可していません)。 -詳細については、不変のコレクションタイプに関するGuavaのユーザーガイドの記事を参照してください。

解説 (4)

これを行う直接的な方法はありません-JavaにはMapリテラルはありません(まだ-Java 8に提案されたと思います)。

このような人もいます。

Map test = new HashMap(){{
       put("test","test"); put("test","test");}};

これにより、HashMapの匿名サブクラスが作成され、インスタンスイニシャライザーがこれらの値を配置します。 (ちなみに、マップには同じ値を2倍に含めることはできません。2番目のputが最初の値を上書きします。 次の例では、さまざまな値を使用します。)。

通常の方法はこれです(ローカル変数の場合)。

Map test = new HashMap();
test.put("test","test");
test.put("test1","test2");

testマップがインスタンス変数である場合は、初期化をコンストラクターまたはインスタンス初期化に配置します。

Map test = new HashMap();
{
    test.put("test","test");
    test.put("test1","test2");
}

testマップがクラス変数の場合は、初期化を静的初期化に配置します。

static Map test = new HashMap();
static {
    test.put("test","test");
    test.put("test1","test2");
}

マップを変更しない場合は、初期化後にマップを Collections.unmodifiableMap(。..)。 これは静的イニシャライザでも実行できます。

static Map test;
{
    Map temp = new HashMap();
    temp.put("test","test");
    temp.put("test1","test2");
    test = Collections.unmodifiableMap(temp);
}

(これで「テスト」を最終的にできるかどうかはわかりません。 ... 試して、ここで報告してください。)。

解説 (0)
Map test = new HashMap()
{
    {
        put(key1, value1);
        put(key2, value2);
    }
};
解説 (8)

プレーンJava 7クラスとvarargsを使用する代替案:この方法でクラス「HashMapBuilder」を作成します。 。

public static HashMap build(String... data){
    HashMap result = new HashMap();

    if(data.length % 2 != 0) 
        throw new IllegalArgumentException("Odd number of arguments");        

    String key = null;
    Integer step = -1;

    for(String value : data){
        step++;
        switch(step % 2){
        case 0: 
            if(value == null)
                throw new IllegalArgumentException("Null key value"); 
            key = value;
            continue;
        case 1:             
            result.put(key, value);
            break;
        }
    }

    return result;
}

次のような方法を使用します。

HashMap data = HashMapBuilder.build("key1","value1","key2","value2");
解説 (2)