はじめに
配列なんて時代遅れ、なんて煽られる可能性すら示唆される(されません)今日のこの頃、HashMapで、特にLinkedHashMapを使う機会があったので、自分用にメモする。
用途
Map系統には、いくつかの種類がある。普通に入れたり取り出したりする分には、どれを使ってもあまり変わりはないのだけど、入っている中のものを管理するときに、大きな違いが出る。
名前 | 違い |
---|---|
HashMap | keyとvalueの並びが適当 |
Hashtable | keyが降順になる |
TreeMap | keyが昇順になる |
LinkedHashMap | FIFO,LRU(getされた順) |
基本的には、putしてgetするだけ。他に何かをするわけじゃない。ただ、keyを同じ名前にすると、あれになるから注意が必要である。valueは同じでもkeyが異なれば上書きされることも無い。下のコードは、loopを設定した分だけけ出力を続ける。
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で宣言すると、こんな感じになった
//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