ソートされたデータのためのTreeMap
- 単語の頻度が求まったら、頻度順にソートしてみたくなる。
- HashMap は key (=単語)に順序を与えることはできない。
- TreeMap は HashMap と同様、key と value の組を保持することができるデータ構造
- java.util.TreeMap は key 同士の値を比較して、その順序を木構造で表したデータ構造。
- key の順序づけには、key 同士を比較するためのクラスを用意する。そのクラスは Comparator インタフェースを実装する。
- ソート自体は Java であらかじめ用意されたアルゴリズムで実行される。
TreeMap のコンストラクタ
- TreeMap<K,V>(Comparator c)
- 指定の Comparator (比較のためのクラス)に従ってソートされる、新しい空のマップを作成する。
TreeMap のメソッド
- boolean containsKey(K key)
- マップが指定のキーのマッピングを保持する場合に true を返す。
- V get(K key)
- この識別情報ハッシュマップで指定されたキーにマップされている値を返す。
- Set<K> keySet()
- マップに格納されているキーのセットビューを返す。
- V put(K key, V value)
- 指定の値と指定されたキーをこのマップに関連付ける。
- void putAll(Map<K,V> map)
- 指定のマップからすべてのマッピングをこのマップにコピーする。
- V remove(Object key)
- キーに対するマッピングがあれば、そのキーをマップから削除する。
- int size()
- マップ内のキー値マッピングの数を返す。
インタフェース Comparator<T> のメソッド
- int compare(T o1, T o2)
- 順序付けのために 2 つの引数を比較する。
最初の引数が 2 番目の引数より小さい場合は負の整数、両方が等しい場合は 0、
最初の引数が 2 番目の引数より大きい場合は正の整数を返す。
コード例
import java.util.HashMap;
import java.util.TreeMap;
import java.util.Map;
import java.util.Set;
import java.util.Comparator;
import java.util.Iterator;
import java.util.Scanner;
public class WordListSorter {
public static void main(String[] args) {
HashMap<String, Integer> termMap = new HashMap<String, Integer>();
// 標準入力からテキストを読み、termMap に単語とその頻度を入れる
Scanner scanner = new Scanner(System.in);
while(scanner.hasNext()) {
String word = scanner.next();
int count = 1;
if(termMap.containsKey(word)){
count += termMap.get(word);
}
termMap.put(word, count);
}
// 比較のためのクラスを指定して TreeMap を生成
TreeMap<String, Integer> treeMap =
new TreeMap<String, Integer>(new IntegerMapComparator(termMap));
// TreeMap に全部の組をコピー(このときにソートされる)
treeMap.putAll(termMap);
// TreeMap の表示
Set<String> termSet = treeMap.keySet(); // ソートされている
Iterator<String> iterator = termSet.iterator();
while(iterator.hasNext()) {
String key = iterator.next();
int value = treeMap.get(key);
System.out.println(key + ": " + value);
}
}
}
/** Map の value でソートするための比較のクラス */
class IntegerMapComparator implements Comparator<String> {
private Map<String, Integer> map;
public IntegerMapComparator(Map<String, Integer> map) {
this.map = map;
}
/** key 2つが与えられたときに、その value で比較 */
public int compare(String key1, String key2) {
// value を取得
int value1 = map.get(key1);
int value2 = map.get(key2);
// value の降順, valueが等しいときは key の辞書順
if(value1 == value2)
return key1.toLowerCase().compareTo(key2.toLowerCase());
else if(value1 < value2)
return 1;
else
return -1;
}
}