【Java】Progateで取り上げられていないJavaの基本まとめ~その3・Map編~

# Map

## 1.Mapとは何か

●`Map`はキーと値をペアにして扱う為のもの。
>`コレクション`との違いについて
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/391581/678dd406-8b50-d218-fe9a-04d2b3205e11.png)
・コレクション・インターフェースは、枝分かれしたインターフェースの階層構造のルーツにある。
・コレクションには、要素の重複を許すコレクションもあれば、許さないものもあったりする。また、順序が付けられたものもあれば、そうでないものもある。
・このコレクションの特徴ごとにサブインターフェースが定義されている。次の図は、ルーツにあたるCollectionから枝分かれした主要なサブインターフェースを示している。
・ちなみに、Mapもコレクションに似ているがコレクションではない。
引用元: https://eng-entrance.com/java-collection

●`Map`を使用する為には`java.util.Map`を`import`する必要がある
●`Map`はインターフェースである為、実装を持たない。その為Mapインターフェースを実装したクラスも`import`する必要がある

## Mapを実装するクラス

### HashMap

```Main.java:
import java.util.map;
import java.util.HashMap;

public class Main {
  public static void main(String[] args) {
    Map<String, String> map = new HashMap<>();
    System.out.println(map);
  }
}
```



### TreeMap

### LinkedHashMap

## 2.プリミティブ型を扱う時は?

`Map`で`int`や`long`などのプリミティブ型を扱うことはできない。
これらを扱う場合はプリミティブ型のラッパークラス、`Integer`, `Long`などを使用する。

```Main.java:
import java.util.Map;
import java.util.Hashmap;

public class Main {
  public static void main(String[] args) {
    Map<Integer, String> map = new HashMap<>();
    System.out.println(map);
  }
}
```

## 3.Mapの基本メソッド

### 1)put
第一引数にキー、第二引数に値をとり、Mapにキーと値を追加する。
返り値は、Mapに同じキーが登録されていればその値、なければ`null`。

```java:
  Map<String, String> map = new HashMap<>();
  map.put("a", "Apple");
  map.put("b", "Banana");
  System.out.println(map);


// > {a=Apple, b=Banana}
```

putで値の上書きもできる。

```java:
  Map<String, String> map = new HashMap<>();
  map.put("a", "Apple");
  map.put("b", "Banana");

  map.put("a", "Anaconda");
  map.put("b", "Bison");

  System.out.println(map);

// > {a=Anaconda, b=Bison}

```

### 2)get
Mapからキーを指定して値を取得する。
指定されたキーがMapにない場合は`null`を返す。

```java:
    Map<String, String> map = new HashMap<>();
    map.put("a", "Apple");
    map.put("b", "Banana");

    System.out.println(map.get("a"));
    System.out.println(map.get("c"));

// > Apple
//   null
```

### 3)getOrDefault

Mapから値を取り出す際に値がなかったらデフォルト値を返す。

```java:
    Map<String, String> map = new HashMap<>();
    map.put("a", "Apple");
    map.put("b", "Banana");
  
    System.out.println(map.getOrDefault("a", "Anime"));
    System.out.println(map.getOrDefault("c", "Cartoon"));

// > Apple
//   Cartoon
```

### 4)size

Mapのサイズ(要素の個数)を取得する。

```java:
    System.out.println(map.size());

// > 2
```

### 5)containsKey

Mapに指定のキーがあるかどうかを確認する。
真偽値が返ってくる。

```java:
    Map<String, String> map = new HashMap<>();
    map.put("a", "Apple");
    map.put("b", "Banana");

    System.out.println(map.containsKey("a"));
    System.out.println(map.containsKey("c"));

// >true
//  false
```


### 6)containsValue

Mapに指定の値があるかどうかを確認する。
真偽値が返ってくる。

```java:
    Map<String, String> map = new HashMap<>();
    map.put("a", "Apple");
    map.put("b", "Banana");

    System.out.println(map.containsKey("Apple"));
    System.out.println(map.containsKey("Cherry"));

// >true
//  false
```

### 7)putAll

```java:
    Map<String, String> map = new HashMap<>();
    map.put("a", "Apple");
    map.put("b", "Banana");

    Map<String, String> map2 = new HashMap<String, String>();
    map2.put("c", "Cherry");
    map2.put("d", "Donut");

    map.putAll(map2);
    System.out.println(map);

// > {a=Apple, b=Banana, c=Cherry, d=Donut}
```

### 8)putIfAbsent

Mapにキーが登録されていなかった場合だけ、値を登録する。

```java:

    Map<String, String> map = new HashMap<>();
    map.put("a", "Apple");
    map.put("b", "Banana");

    map.putIfAbsent("a", "Almond");
    map.putIfAbsent("c", "Cherry");

    System.out.println(map);

// > {a=Apple, b=Banana, c=Cherry}

```

### 9)remove(key)

キーを指定して値を削除する。
指定した（削除した）キーに対応する値が返ってくる。
キーがなければ`null`を返す。

```java:

    Map<String, String> map = new HashMap<>();
    map.put("a", "Apple");
    map.put("b", "Banana");

    map.remove("a");
    System.out.println(map);

// > {b=Banana}
```


### 10)remove(key, value)

キーに対応する値が指定の値だった場合のみ削除する。
返り値は真偽値で、削除が実行されたら`true`を返す。

```java:

    Map<String, String> map = new HashMap<>();
    map.put("a", "Apple");
    map.put("b", "Banana");

    map.remove("a", "Almond");
    map.remove("b", "Banana");

    System.out.println(map);

// > {a=Apple}
```

### 11)clear

Mapをクリアする。

```java:

    Map<String, String> map = new HashMap<>();
    map.put("a", "Apple");
    map.put("b", "Banana"); 

    map.clear();
    System.out.println(map);

// > {}

```


## 4.Mapのループ処理

### 1)キーのループ処理

```java:

import java.util.Map;
import java.util.HashMap;
import java.util.Iterator;

public class Main {
  public static void main(String[] args) {
    Map<String, String> map = new HashMap<>();
    map.put("a", "Apple");
    map.put("b", "Banana");
    map.put("c", "Cherry");
    map.put("d", "Donut");
    map.put("e", "Egg");

    Iterator<String> it = map.keySet().iterator();
    while (it.hasNext()) {
      String key = it.next();
      System.out.println(key);
    }
  }
}

/* > a
     b
     c
     d
     e
*/

```

①`keySet()`メソッドを使い、Mapのキーだけをコレクションとして取得する
②keySetから`iterator()`を取得することでループ処理ができるようになる

##### `iterator`とは?
コレクション(=要素の大きさ・数が決まっていない配列みたいなもの)のループ処理に便利なインターフェース

##### `hasNext()`メソッドと`next()`メソッド
hasNextメソッド: 次の要素があればtrue、なければfalseを返す
nextメソッド: 次の要素を返す
`iterator`インターフェースを実装するのに必要となるメソッド。

### 2)値のループ処理

```java:

import java.util.Map;
import java.util.HashMap;
import java.util.Iterator;

public class Main {
  public static void main(String[] args) {
    Map<String, String> map = new HashMap<>();
    map.put("a", "Apple");
    map.put("b", "Banana");
    map.put("c", "Cherry");
    map.put("d", "Donut");
    map.put("e", "Egg");

    Iterator<String> it = map.values().iterator();
    while (it.hasNext()) [
      String key = it.next();
      System.out.println(key);
    }
  }
}

/* > Apple
     Banana
     Cherry
     Donut
     Egg

*/
```

①`values()`メソッドを使い、Mapの値をコレクションとして取得する
②そのkeySetから`iterator()`を取得することでループ処理ができるようになる


### 3)キーと値のループ処理

```java:

import java.util.Map;
import java.util.HashMap;
import java.util.Iterator;

public class Main {
  public static void main(String[] args) {
    Map<String, String> map = new HashMap<>();
    map.put("a", "Apple");
    map.put("b", "Banana");
    map.put("c", "Cherry");
    map.put("d", "Donut");
    map.put("e", "Egg");

    Iterator<String> it = map.entrySet().iterator();
    while (it.hasNext()) [
      Map.Entry<String, String> entry = it.next();
      System.out.println(entry.getKey() + " = " + entry.getValue());
    }
  }
}


/* > a = Apple
     b = Banana
     c = Cherry
     d = Donut
     e = Egg
*/

```

##### `entrySet()`メソッド
Mapのキーと値をコレクションとして取得する為のメソッド。
このコレクションの中身は`Map.Entry`というクラス。

##### `getKey()`と`getValue()`メソッド
`Map.Entry`クラスがもつメソッド。
getKey() : キーを取得
getValue() : 値を取得


### 4)for文を使ってループ処理

配列用のfor文、についてはprogateでも取り上げられている内容です。
忘れてしまったらprogateを復習してみましょう。

```java:
// 省略 //

    for (map.Entry<String, String> entry : map.entrySet() {
      System.out.println(entry.getKey() + " = " + entry.getValue());
    }
  
/* > a = Apple
     b = Banana
     c = Cherry
     d = Donut
     e = Egg
*/
```

### 5)forEachを使ってループ処理

java8以降、ラムダ式でキーと値のループ処理ができるようになった。
それが`forEach()`メソッド。

```java:

    forEach ((key, value) -> {
      System.out.println(key + " = " + value);
    });
  
/* > a = Apple
     b = Banana
     c = Cherry
     d = Donut
     e = Egg
*/
```