web-dev-qa-db-ja.com

HashMapを(文字通りの方法で)直接初期化する方法

このようにJava HashMapを初期化する方法はありますか?

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

正しい構文は何でしょうか。私はこれに関して何も見つけていません。これは可能ですか?私はいくつかの "final/static"値をマップに入れるための最短/最速の方法を探しています。

894
jens

Javaバージョン9以降の場合

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

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

// this works for any number of elements:
Map<String, String> 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 および Javadoc も参照)

Javaバージョン8まで

いいえ、すべての要素を手動で追加する必要があります。無名サブクラスで初期化子を使用して、構文を少し短くすることができます。

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

ただし、無名サブクラスは、場合によっては望ましくない動作を引き起こす可能性があります。

初期化に関数を使用しても同じことができますが、コードの可読性が向上します。

Map<String, String> myMap = createMap();

private static Map<String, String> createMap() {
    Map<String,String> myMap = new HashMap<String,String>();
    myMap.put("a", "b");
    myMap.put("c", "d");
    return myMap;
}
1084
yankee

これは一方通行です。

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

ただし、注意して、上記のコードを確実に理解してください(HashMapから継承した新しいクラスが作成されます)。したがって、ここでもっと読むべきです: http://www.c2.com/cgi/wiki?DoubleBraceInitialization または単にGuavaを使う:

Map<String, Integer> left = ImmutableMap.of("a", 1, "b", 2, "c", 3);
991
gregory561

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

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

これは 5までのキー/値の組 で動作します。それ以外の場合は ビルダー を使用できます。

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


315
Jens Hoffmann

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

これを好む人もいます。

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

これはHashMapの無名サブクラスを作成し、そのインスタンス初期化子はこれらの値を置きます。 (ところで、マップに同じ値を2回含めることはできません。2回目の書き込みで最初の値が上書きされます。次の例では異なる値を使用します。)

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

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

testマップがインスタンス変数の場合は、初期化をコンストラクタまたはインスタンス初期化子に入れます。

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

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

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

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

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

testをfinalにできるかどうかはわかりません。試してみて、ここに報告してください。)

100
Paŭlo Ebermann
Map<String,String> test = new HashMap<String, String>()
{
    {
        put(key1, value1);
        put(key2, value2);
    }
};
60
Shaggy Frog

もう1つの方法は、プレーンなJava 7クラスと可変引数を使用することです。このメソッドでクラスHashMapBuilderを作成します。

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

    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<String,String> data = HashMapBuilder.build("key1","value1","key2","value2");
42
Aerthel