DoubleWideMap

9月7日に、2重のMap を書いた。
http://blog.zaq.ne.jp/oboe2uran/article/262/

この時、2つのKeyの型は同じである約束になっている。
ならば、異なる型のKeyを指定できるものも存在した方がより便利であろう。
以下、型 P という第2Key を表現することにして、、、
インタフェースは、、、

import java.util.Collection;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;

public interface DoubleWideMap<K,P,V>{
   public V put(K key1,P key2,V value);
   public Map<P,V> put(K key1,Map<P,V> map);
   public V get(K key1,P key2);
   public Map<P,V> get(K key1);
   public boolean containsKey(K key1);
   public boolean containsKey(K key1,P key2);
   public int size();
   public int size(K key1);
   public Set<K> keySet();
   public Set<P> keySet(K key1);
   public Collection<Map<P,V>> values();
   public Collection<V> values(K key1);
   public void clear();
   public void clear(K key1);
   public Map<P,V> remove(K key1);
   public V remove(K key1,P key2);
   public Set<Entry<K,Map<P,V>>> entrySet();
   public boolean equals(Object o);
   public int hashCode();
}
------- そして実装は、TreeMapなら、、、
import java.util.Collection;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.Map.Entry;

public class DoubleWideTreeMap<K,P,V> implements DoubleWideMap<K,P,V>{
   private Map<K,Map<P,V>> map;
   private Comparator<? super P> cmp2;
   public DoubleWideTreeMap(){
      this.map = new TreeMap<K,Map<P,V>>();
      this.cmp2 = null;
   }
   public DoubleWideTreeMap(Comparator<? super K> comparator){
      this.map = new TreeMap<K,Map<P,V>>(comparator);
      this.cmp2 = null;
   }
   public DoubleWideTreeMap(Comparator<? super K> comparator1,Comparator<? super P> comparator2){
      this.map = new TreeMap<K,Map<P,V>>(comparator1);
      this.cmp2 = comparator2;
   }
   @Override
   public V put(K key1,P key2,V value){
      if (!this.map.containsKey(key1)){
         this.map.put(key1,this.cmp2==null ? new TreeMap<P,V>() : new TreeMap<P,V>(this.cmp2));
      }
      return this.map.get(key1).put(key2,value);
   }
   @Override
   public Map<P,V> put(K key1,Map<P,V> m){
      return this.map.put(key1,m);
   }
   @Override
   public Map<P,V> get(K key1){
      return this.map.get(key1);
   }
   @Override
   public V get(K key1,P key2){
      return this.map.get(key1).get(key2);
   }
   @Override
   public Set<K> keySet(){
      return this.map.keySet();
   }
   @Override
   public Set<P> keySet(K key1){
      return this.map.containsKey(key1) ? this.map.get(key1).keySet() : new HashSet<P>();
   }
   @Override
   public Collection<Map<P,V>> values(){
      return this.map.values();
   }
   @Override
   public Collection<V> values(K key1){
      return this.map.get(key1).values();
   }
   @Override
   public boolean containsKey(K key1){
      return this.map.containsKey(key1);
   }
   @Override
   public boolean containsKey(K key1,P key2){
      return this.map.containsKey(key1) ? this.map.get(key1).containsKey(key2) : false;
   }
   @Override
   public int size(){
      return this.map.size();
   }
   @Override
   public int size(K key1){
      return this.map.containsKey(key1) ? this.map.get(key1).size() : 0;
   }
   @Override
   public void clear(){
      this.map.clear();
   }
   @Override
   public void clear(K key1){
      this.map.get(key1).clear();
   }
   @Override
   public Map<P,V> remove(K key1){
      return this.map.remove(key1);
   }
   @Override
   public V remove(K key1,P key2){
      return this.map.get(key1).remove(key2);
   }
   @Override
   public Set<Entry<K,Map<P,V>>> entrySet(){
      return this.map.entrySet();
   }
   @SuppressWarnings("unchecked")
   @Override
   public boolean equals(Object o){
      DoubleWideMap<K,P,V> m2 = (DoubleWideMap<K,P,V>)o;
      return this.map.entrySet().equals(m2.entrySet());
   }
   @Override
   public int hashCode(){
      return this.map.hashCode();
   }
   @Override
   public String toString(){
      StringBuffer sb = new StringBuffer();
      for(Iterator<K> it=this.map.keySet().iterator();it.hasNext();){
         K key1 = it.next();
         sb.append(key1+"={");
         Map<P,V> map2 = this.map.get(key1);
         for(Iterator<P> it2=map2.keySet().iterator();it2.hasNext();){
            P key2 = it2.next();
            sb.append(key2+"="+map2.get(key2));
            if (it2.hasNext()) sb.append(", ");
         }
         sb.append("}");
         if (it.hasNext()) sb.append(", ");
      }
      return "{"+sb.toString()+"}";
   }
}