【 Java 】Mapの実装クラスについて


## ■ Mapとは
「java.util」パッケージにあるインタフェースで、「キー」に「値」をマッピングするオブジェクトとのこと。
キーを目印に値を探すことができるので、JSON形式の値を扱うのに適しているのかな〜と考えてます。

## ■ いろんな実装クラス
Mapはインタフェースなため、そのままでは使えません。
使うためには実装が必要なわけですが、よく見かける実装クラスの下記3つを今回は調べてみようと思います。

① HashMap
   ② LinkedHashMap
   ③ TreeMap

## ■ それぞれの特徴
<table>
  <thead>
    <tr>
      <th>実装クラス</th>
      <th>null値</th>
      <th>順序</th>
    </tr>
  </thead>
  <tr>
    <td>HashMap</td>
    <td>許容される</td>
    <td>保証されない</td>
  </tr>
  <tr>
    <td>LinkedHashMap</td>
    <td>許容される</td>
    <td>挿入順</td>
  </tr>
  <tr>
    <td>TreeMap</td> 
    <td>許容される <br>※キーへのnullは許容されない</td>
    <td>ソート順</td>
  </tr>
</table>

:::note warn
※ Mapはキーの重複は許容されていない。
キーのnullは1つのみ、値のnullは複数あってもよしということ。
:::

## ■ HashMapの場合
```java:HashMapの特徴
    // HashMap初期化
    Map<Integer,String> hashMap = new HashMap<>();
    
    // キーと値を挿入
    hashMap.put(null, null);
    hashMap.put(2,null);
    hashMap.put(1, "One");
    
    // hashMapに挿入したキーと値を全て出力
    for (Map.Entry<Integer, String> entry : hashMap.entrySet()) {
      System.out.println(entry.getKey() + " : " + entry.getValue());
    }

    // 出力結果 
    // ※null値の許容、順序が保証されていないことが確認できる。
      null : null
      1 : One
      2 : null
```

## ■ LinkedHashMapの場合
```java:LinkedHashMapの特徴
    // LinkedHashMap初期化
    Map<Integer,String> linkedHashMap = new LinkedHashMap<>();
		
    // キーと値を挿入
    linkedHashMap.put(null, null);
    linkedHashMap.put(2,null);
    linkedHashMap.put(1, "One");
    
    // linkedHashMapに挿入したキーと値を全て出力
    for (Map.Entry<Integer, String> entry : linkedHashMap.entrySet()) {
      System.out.println(entry.getKey() + " : " + entry.getValue());
    }

    // 出力結果 
    // ※null値の許容、順序が挿入順になっていることが確認できる。
      null : null
      2 : null
      1 : One
```

## ■ TreeMapの場合
```java:TreeMapの特徴　※キーにnullを挿入
    // TreeMap初期化
    Map<Integer,String> treeMap = new TreeMap<>();
    
    // キーと値を挿入
    treeMap.put(null, null);
    treeMap.put(2,null);
    treeMap.put(1, "One");
    
    // TreeMapに挿入したキーと値を全て出力
    for (Map.Entry<Integer, String> entry : treeMap.entrySet()) {
      System.out.println(entry.getKey() + " : " + entry.getValue());
    }

    // 出力結果
    // 1つ目のキーにnullを挿入しているためエラーとなる。
      Exception in thread "main" java.lang.NullPointerException:
      Cannot invoke "java.lang.Comparable.compareTo(Object)" because "k1" is null
      at java.base/java.util.TreeMap.compare(TreeMap.java:1569)
	  at java.base/java.util.TreeMap.addEntryToEmptyMap(TreeMap.java:776)
	  at java.base/java.util.TreeMap.put(TreeMap.java:785)
	  at java.base/java.util.TreeMap.put(TreeMap.java:534)
	  at Maps.main(Maps.java:17)
```
エラー原因となっている箇所を修正↓

```java:TreeMapの特徴
    // LinkedHashMap初期化
    Map<Integer,String> treeMap = new TreeMap<>();
    
    // キーと値を挿入
    treeMap.put(3, null);
    treeMap.put(2,null);
    treeMap.put(1, "One");
    
    // TreeMapに挿入したキーと値を全て出力
    for (Map.Entry<Integer, String> entry : treeMap.entrySet()) {
      System.out.println(entry.getKey() + " : " + entry.getValue());
    }
    
    // 出力結果
    // ※null値の許容、順序がソート(昇順)になっていることが確認できる。
      1 : One
      2 : null
      3 : null
```

## ■ 最後に
今回は、Javaで使われるMapの実装クラスの特徴を確認してみました。
使用用途に応じてどのクラスを使えばいいか分かりました。
次回は、Mapの使い方について調べてみようと思います。
[→Mapの使い方調べてみました！](https://qiita.com/devdia/items/cb8d8f44579de3e33b45)

## ■ 参照サイト
https://docs.oracle.com/javase/jp/8/docs/api/java/util/HashMap.html

https://docs.oracle.com/javase/jp/8/docs/api/java/util/LinkedHashMap.html

https://docs.oracle.com/javase/jp/8/docs/api/java/util/TreeMap.html