このようにJava HashMapを初期化する方法はありますか?
Map<String,String> test =
new HashMap<String, String>{"test":"test","test":"test"};
正しい構文は何でしょうか。私はこれに関して何も見つけていません。これは可能ですか?私はいくつかの "final/static"値をマップに入れるための最短/最速の方法を探しています。
はい、これは今可能です。 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")
);
上の例では、test
とtest2
の両方が同じになり、Mapの表現方法が異なります。 Map.of
メソッドはマップ内の最大10個の要素に対して定義されますが、Map.ofEntries
メソッドはそのような制限を持ちません。
この場合、結果のマップは不変マップになります。地図を変更可能にしたい場合は、もう一度コピーします。 mutableMap = new HashMap<>(Map.of("a", "b"));
を使う
いいえ、すべての要素を手動で追加する必要があります。無名サブクラスで初期化子を使用して、構文を少し短くすることができます。
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;
}
これは一方通行です。
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);
サードパーティのライブラリを許可する場合は、 Guava の ImmutableMap を使用して、文字通りの簡潔さを実現できます。
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();
これを行う直接的な方法はありません。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にできるかどうかはわかりません。試してみて、ここに報告してください。)
Map<String,String> test = new HashMap<String, String>()
{
{
put(key1, value1);
put(key2, value2);
}
};
もう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");