TreeMapのキーに注意
同期がJavaではまっていて,ミイラを取ろうとしてミイラになっちゃった.なんとか解決したのでメモ.今思えば当たり前なのだけれど,TreeMapのキーObjectはComparableを実装しておく必要がある.TreeMapはキーをソートしておいて,探索効率をあげてくれる.そのためComparableインタフェースが必要なのだ.
実装されてなかったらhashCode()とかで比較せいやーと思っちゃうんだけれど,そんなゆとり発言は許されないらしい.院生になってからまともにJava触ったことなかったけれど,generics機能がとてもよい(といってもC++のテンプレート機能なんだけど),ものすごく便利になってた.よくよく考えたらほとんど全てのデータ構造が既にクラスとして用意されてるんだよなぁ.3種類のデータ型(スカラーと配列とハッシュ)しか存在しない世界にどっぷり使っている自分て一体...
以下,自前でComparableを実装したHashMapオブジェクトをキーにしたTreeMapの使用例.これだとTreeMap使う恩恵が全くわからんなぁw
extendsする際にgenerics機能を引き継ぐために
import java.util.*; class TreeMapTest{ public static void main(String args[]){ Hoge h = new Hoge(); /* Comparableが実装されていないので,エラーが出る */ /* HashMap<String, Integer> h1 = new HashMap<String, Integer>(); h.addCount(h1); h.addCount(h1); h.addCount(h1); h.showCount(h1); */ /* Comparableを実装したので,うまく動く */ MyHashMap<String, Integer> h2 = new MyHashMap<String, Integer>(); h.addCount(h2); h.addCount(h2); h.showCount(h2); } } class Hoge{ private TreeMap<MyHashMap<String, Integer>, Integer> hogeTree; public Hoge(){ this.hogeTree = new TreeMap<MyHashMap<String, Integer>, Integer>(); } public void addCount(MyHashMap<String, Integer> tmpHash){ if(this.hogeTree.containsKey(tmpHash)){ int count = this.hogeTree.get(tmpHash); count++; this.hogeTree.put(tmpHash, count); }else{ this.hogeTree.put(tmpHash, 1); } } public void showCount(MyHashMap<String, Integer> tmpHash){ if(this.hogeTree.containsKey(tmpHash)){ System.out.println("Count of tmpHash = " + this.hogeTree.get(tmpHash)); }else{ System.out.println("hogeTree does NOT contain tmpHash."); } } } class MyHashMap<K,V> extends HashMap implements Comparable{ public int compareTo(Object o){ return this.hashCode() - o.hashCode(); } }