HashMapで複数のvalueを持たせるメモ

# はじめに
　配列なんて時代遅れ、なんて煽られる可能性すら示唆される（されません）今日のこの頃、HashMapで、特にLinkedHashMapを使う機会があったので、自分用にメモする。

# 用途
　Map系統には、いくつかの種類がある。普通に入れたり取り出したりする分には、どれを使ってもあまり変わりはないのだけど、入っている中のものを管理するときに、大きな違いが出る。

|名前|違い|
|:-----------------:|:------------------:|
|HashMap| keyとvalueの並びが適当 |
|Hashtable|keyが降順になる|
|TreeMap|keyが昇順になる|
|LinkedHashMap|FIFO,LRU(getされた順)|


基本的には、putしてgetするだけ。他に何かをするわけじゃない。ただ、keyを同じ名前にすると、あれになるから注意が必要である。valueは同じでもkeyが異なれば上書きされることも無い。下のコードは、loopを設定した分だけけ出力を続ける。

```Java:Sample.java
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

public class Main {

	public static void main(String[] args) {
		int loop = 50;
		 // Mapの宣言
        Map<String, Integer> map = new HashMap<String, Integer>();
        
        // Mapに要素を追加
        map.put("uni", 1);
        map.put("kura", 2);
        map.put("kurage", 3);
        map.put("nameko", 4);
        map.put("nameko", 5);
        
         // イテレーターをまわす
        Iterator<Map.Entry<String, Integer>> itr = map.entrySet().iterator();
        
        // key, valueの取得
        while(true) {
            // nextを使用して値を取得する
            Map.Entry<String, Integer> entry = itr.next();
            
            //最終までいったら、最初に戻る
            if(!itr.hasNext()) {
            	if(loop < 0) {
            		break;
            	}
            	loop--;
            	itr = map.entrySet().iterator();
            	
            }
            System.out.println(entry.getKey() + " : " + entry.getValue());
        }
	}

}
```
上記のコードで注意すべき点は、入れた順に出てくるわけではないということです。普通のMapなので、別のにする必要がある。困ったら、LinkedHashMapを使えばいいと思う。それぞれの詳しくは、それぞれの説明を読みに行ってほしい。

# 複数のvalueを持たせる
　 今回、ちょっとしたことなんだけど、keyに対して、valueを2つ持たせなくてはいけなくなった。とりあえず、ListをMapの中で持たせられることが分かった。初心者の私には複雑で怒っている構造になっている。ListはMapと違って、addで入れて、getで取得する。
　イメージとしてはこんなん：key="unikura",value={1993,25}
これをLinkedHashMapのLRUで宣言すると、こんな感じになった



```Java:LinkedHashMap
//3つ目の引数が重要
//false：FIFO（デフォルト）、true：LRU
    LinkedHashMap<String, List<Integer>> Samplekey = new LinkedHashMap<String, List<Integer>>(30, 0.75f, true);
    List<Integer> Samplevalues = new ArrayList<Integer>();
```

インターフェースの概念的に（分からん）、分けて書くのが普通らしい。下の書き方が普通っぽいので、そっちを使ってほしい。Mapも同じ感じかな。

```
List<データ型> リスト名 = new ArrayList<データ型>(初期サイズ); 
```


ここで、**LinkedList** と **ArrayList** の使い分け方について考える必要が出てきた。今回、私がやろうとしていることにはListの中身を頻繁に書き換える必要がある。**ArrayListは、順序番号がふられているため、特定の要素に対してランダムアクセスが可能である。**LinkedList はそれが出来ないため、ArrayListを使う方がいいのかなと思った。



## 別のクラスで書く（最終的にこっちにした）

```

public class Sample {
    private int populality;
    private int freshness;

    public Sample(int populality, int freshness) {
        this.populality = populality;
        this.freshness = freshness;
    }
    public Sample() {
        this.populality = 0;
        this.freshness = 0;
    }
    public int getPopulality() {
        return populality;
    }
    public void setPopulality(int populality) {
        this.populality = populality;
    }
    public int getFreshness() {
        return freshness;
    }
    public void setFreshness(int freshness) {
        this.freshness = freshness;
    }
}
```

```
private LinkedHashMap<String, Sample> Map = new LinkedHashMap<String, Sample>(30, 0.75f, false);
Sample info = this.Map.get(kename);
int Freshness = info.getFreshness();
int getPopulality = info.getPopulality();
info.setFreshness(0);
info.setPopulality(0);
```


## 最後に
　すいません、ごちゃごちゃになったちゃいました（私だけ分かればいいっていうのもありますけど）valueの個数が少ないなら自分で書いた方がらくっぽいです。


# 参考文献
http://kaworu.jpn.org/kaworu/2008-04-10-2.php
https://code.i-harness.com/ja-jp/q/7d9261
https://www.task-notes.com/entry/20160402/1459595902
https://qiita.com/BumpeiShimada/items/522798a380dc26c50a50