JavaのMapコンテナ
最終更新日27 Feb 2018 07:56
Table of Contents
|
クラス名 | 説明 | 利点 | 欠点 | 自作クラスするときにオーバーライドしなきゃいけないもの |
---|---|---|---|---|
HashMap | キーと値の組からなる要素の集合を扱います。k=vの並びが適当 | 更新処理の速度が一番速い | 普通に入れるとnullが入ったりするんだけど、結構メモリ空間無駄に使ってる?? | equals(),hashCode() |
TreeMap | キーと値の組からなる要素の集合を扱います。キーが昇順(数が小から大へ)でソートされています。subMapが利用できる | getが1番速い | put/removeに時間が掛かる,自作オブジェクトがキーの場合は「java.lang.Comparable」または「java.util.Comparator」を実装しないといけない。 | java.lang.Comparable java.util.Comparator |
LinkedHashMap | k=vを入れた順番に並ぶ | 反復処理の速度は速い | 要素の追加や削除の速度はHashMapよりもいくぶん遅い | |
EnumMap | 早い | enumのみをキーにできる。え、それってただの配列じゃん? | ||
HashTable | 古い。Java2 以前のバージョンとの互換性のために残されているようなもの |
getの速さ | EnumMap>TreeMap>LinkedHashMap>HashMap |
---|---|
putの速さ | EnumMap>LinkedHashMap>HashMap>TreeMap |
初期化
int selectedNumber = 2; final Map<Integer, String> orderWordMap = new HashMap<Integer, String>() {{ put(1, "first"); put(2, "second"); put(3, "third"); }};
走査
キー | it.next() |
---|---|
値 | map.get(キー) |
import java.util.*; class TreeMapTest { public static void main(String[] args) { TreeMap map = new TreeMap(); map.put("Name", "Tanaka"); map.put("Age", new Integer(26)); Iterator it = map.keySet().iterator(); while (it.hasNext()) { Object o = it.next(); System.out.println(o + " = " + map.get(o)); } } }
Collection map_ite2 = hm1.values(); //(7)Mapの値を代入 //(8)Iterator処理 for (Iterator i = map_ite2.iterator(); i.hasNext();) { System.out.println("値のIterator:" + i.next()); }
複数のキーを持つマップ
HashMapの中にHashMapとか、
ArrayListをキーにするとか色々とやり方があるみたいだけど、
それ以外の方法を模索してみます
配列を使う方法
import java.util.*; import java.util.HashMap; class Main { public class Key{ public String key1; public String key2; } public static void main(String[] args) { HashMap<String[],String> map=new HashMap<String[],String>();//ok HashMap<String[2],String> map2=new HashMap<String[2],String>();//error } }
キー用のクラスを作る方法
import java.util.*; import java.util.HashMap; class Main { public class Key{ public String key1; public String key2; @Override// このオブジェクトと「等価」になるオブジェクトがあるかどうかを示します。 public boolean equals(Key obj){ } @Override public int hashCode() {// オブジェクトのハッシュコード値を返します。 } } public static void main(String[] args) { HashMap<Key,String> map3=new HashMap<Key,String>();//ok } }
自作クラスをキーにする場合はequals()とhashCode()をオーバーライドしないといけない。
equals()とhashCode()はjava.lang.Objectにある関数だから、どんなオブジェクトでもいいってこと。
もしAndroidで使用して、かつAPI Level4.4以上ならばArrayMapがおすすめ
mapにputしてから、valueを変えたらどうなるか?
putした時の値が保持される。やっぱり、値渡しなんだね
import java.util.*; class Main { public static void main(String args[]){ HashMap<String,String> map=new HashMap<String,String>(); String key="hello"; String value="I am good."; map.put(key,value); Iterator it = map.keySet().iterator(); while (it.hasNext()) { Object o = it.next(); System.out.println(o + " = " + map.get(o)); } value="value changed"; System.out.println("After value changed"); it = map.keySet().iterator(); while (it.hasNext()) { Object o = it.next(); System.out.println(o + " = " + map.get(o)); } } }
重複チェック
Mapのput()を呼んだら、そのキーで既に何か登録されていた場合は,
何か返ってくる。
そうではなく、初めて登録するものの場合はnullが返ってくる。
一つのキーで複数のオブジェクトを登録したい場合
基本的に値のほうをArrayListなどにするしかない。
Map<String,List<Integer>> map = new HashMap<String,List<Integer>>(); // 登録 List<Integer> list = new ArrayList<Integer>(); list.add(11); list.add(12); map.put("group1", list); // 参照 for ( Integer i : map.get("group1") ) { System.out.println(i); } }
登録する時にちょっとうっとうしいね。
associative-container map