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();
    }
}