1. ホーム
  2. java

[解決済み] HashMapを直接(リテラルに)初期化する方法は?

2022-03-19 17:02:20

質問

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

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

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

解決方法は?

すべてのバージョン

万が一、1項目だけ必要な場合に備えて。次のようなものがあります。 Collections.singletonMap("key", "value") .

Java Version 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:
import static java.util.Map.entry;    
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 と、その ジャバドック )

Javaバージョン8まで対応。

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

Map<String, String> myMap = new HashMap<String, String>() {{
    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;
}