LoginSignup
3
4

More than 1 year has passed since last update.

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

Last updated at Posted at 2019-03-13

はじめに

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

用途

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

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

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

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で宣言すると、こんな感じになった

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<データ型>(初期サイズ); 

ここで、LinkedListArrayList の使い分け方について考える必要が出てきた。今回、私がやろうとしていることには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

3
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
4