JavaでHashMapを初期化する

JavaでHashMapを初期化する

1. 概要

このチュートリアルでは、JavaでHashMap を初期化するさまざまな方法について学習します。

Java8とJava9を使用します。

参考文献:

Javaでの2つのHashMapの比較

Javaで2つのHashMapを比較する方法と、それらの違いを見つける方法を学ぶ

ストリームを使用してマップを操作する

Java MapsとStreamsを組み合わせる方法を学ぶ

2. 静的HashMapの静的初期化子

コードのstaticブロックを使用して、HashMap を初期化できます。

public static Map articleMapOne;
static {
    articleMapOne = new HashMap<>();
    articleMapOne.put("ar01", "Intro to Map");
    articleMapOne.put("ar02", "Some article");
}

この種の初期化の利点は、マップが変更可能であるが、静的に対してのみ機能することです。 エントリは、必要に応じて追加および削除できます。

先に進んでテストしてみましょう。

@Test
public void givenStaticMap_whenUpdated_thenCorrect() {

    MapInitializer.articleMapOne.put(
      "NewArticle1", "Convert array to List");

    assertEquals(
      MapInitializer.articleMapOne.get("NewArticle1"),
      "Convert array to List");
}

二重中括弧構文を使用してマップを初期化することもできます。

Map doubleBraceMap  = new HashMap() {{
    put("key1", "value1");
    put("key2", "value2");
}};

we must try to avoid this initialization technique as it creates an anonymous extra class at every usage, and also holds hidden references to the enclosing objectは、メモリリークの問題を引き起こす可能性があることに注意してください。

3. Javaコレクションの使用

単一のエントリでシングルトンの不変のマップを作成する必要がある場合、Collections.singletonMap() は非常に便利です。

public static Map createSingletonMap() {
    return Collections.singletonMap("username1", "password1");
}

ここの地図は不変であることに注意してください。エントリを追加しようとすると、java.lang.UnsupportedOperationException.がスローされます。

Collections.emptyMap():を使用して、不変の空のマップを作成することもできます

Map emptyMap = Collections.emptyMap();

4. Java 8の方法

ここで、このセクションでは、Java 8Stream API.を使用してマップを初期化する方法を見てみましょう。

4.1. Collectors.toMap()の使用

2次元のString配列のStreamを使用して、それらをマップに収集してみましょう。

Map map = Stream.of(new String[][] {
  { "Hello", "World" },
  { "John", "Doe" },
}).collect(Collectors.toMap(data -> data[0], data -> data[1]));

ここで、キーのデータ型とMapの値が同じであることに注意してください。

より一般的にするために、Objects の配列を取得して、同じ操作を実行しましょう。

 Map map = Stream.of(new Object[][] {
     { "data1", 1 },
     { "data2", 2 },
 }).collect(Collectors.toMap(data -> (String) data[0], data -> (Integer) data[1]));

ここでは、キーのマップをStringとして作成し、値をIntegerとして作成します。

4.2. Map.Entryのストリームを使用する

ここでは、Map.Entry. のインスタンスを使用します。これは、さまざまなキーと値のタイプがある別のアプローチです。

まず、Entry インターフェースのSimpleEntry 実装を使用しましょう。

Map map = Stream.of(
  new AbstractMap.SimpleEntry<>("idea", 1),
  new AbstractMap.SimpleEntry<>("mobile", 2))
  .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));

それでは、SimpleImmutableEntry implementationを使用してマップを作成しましょう。

Map map = Stream.of(
  new AbstractMap.SimpleImmutableEntry<>("idea", 1),
  new AbstractMap.SimpleImmutableEntry<>("mobile", 2))
  .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));

4.3. 不変マップの初期化

特定のユースケースでは、不変のマップを初期化する必要があります。 これは、Collectors.toMap()Collectors.collectingAndThen()内にラップすることで実行できます。

Map map = Stream.of(new String[][] {
    { "Hello", "World" },
    { "John", "Doe" },
}).collect(Collectors.collectingAndThen(
    Collectors.toMap(data -> data[0], data -> data[1]),
    Collections:: unmodifiableMap));

Streams, を使用したこのような初期化は使用しないでください。パフォーマンスのオーバーヘッドが大きくなり、マップを初期化するためだけに大量のガベージオブジェクトが作成される可能性があります。

5. Java 9の方法

Java 9には、Mapインターフェースにさまざまなファクトリメソッドが付属しており、不変のマップの作成と初期化を簡素化します。

先に進んで、これらのファクトリメソッドを調べてみましょう。

5.1. Map.of()

このファクトリメソッドは、引数なし、単一の引数、および可変引数を取ります。

Map emptyMap = Map.of();
Map singletonMap = Map.of("key1", "value");
Map map = Map.of("key1","value1", "key2", "value2");

このメソッドは、最大10のキーと値のペアのみをサポートすることに注意してください。

5.2. Map.ofEntries()

Map.of() に似ていますが、キーと値のペアの数に制限はありません。

Map map = Map.ofEntries(
  new AbstractMap.SimpleEntry("name", "John"),
  new AbstractMap.SimpleEntry("city", "budapest"),
  new AbstractMap.SimpleEntry("zip", "000000"),
  new AbstractMap.SimpleEntry("home", "1231231231")
);

ファクトリメソッドは不変のマップを生成するため、変更を加えるとUnsupportedOperationException. になることに注意してください。

また、重複キーと同様にヌルキーも許可しません。

これで、初期化後に可変または拡大するマップが必要な場合は、Mapインターフェースの実装を作成して、これらの不変マップをコンストラクターに渡すことができます。

Map map = new HashMap (
  Map.of("key1","value1", "key2", "value2"));
Map map2 = new HashMap (
  Map.ofEntries(
    new AbstractMap.SimpleEntry("name", "John"),
    new AbstractMap.SimpleEntry("city", "budapest")));

6. グアバの使用

コアJavaの使用方法を調べたので、次に進み、ApacheGuavaを使用してマップを初期化します。

Map articles
  = ImmutableMap.of("Title", "My New Article", "Title2", "Second Article");

これにより、不変マップが作成され、可変マップが作成されます。

Map articles
  = Maps.newHashMap(ImmutableMap.of("Title", "My New Article", "Title2", "Second Article"));

メソッドImmutableMap.of() は、key1、value1、key2、value2などの形式でvar-argsを取得します。

ImmutableMap.of("key1", "value1", "key2", "value2");

7. 結論

この記事では、Mapを初期化するさまざまな方法、特に空のシングルトンの不変および可変のマップを作成する方法について説明しました。 As you can see, there’s a huge improvement in this field since Java 9.

いつものように、サンプルソースコードはGithub projectにあります。 Java 9の例はhereにあり、Guavaサンプルはhereにあります。