Monday, December 17, 2007

Behavioral Differences Between HashMap and TreeMap

import java.util.*;
import static java.lang.System.*;

public class Doppleganger implements Comparable {
    int hashValue; 
    
    @Override
    public int compareTo(Object other) { 
     Doppleganger dg = (Doppleganger) other;
     return hashValue==dg.hashCode()?0:hashValue<dg.hashCode()?-1:1;
    }
    void setHashValue(int hash) {
       this.hashValue = hash;
    }
    
    @Override
    public int hashCode() {
       return this.hashValue;
    }

    public static void main(String[] args) {
       Doppleganger dg1 = new Doppleganger();
       Doppleganger dg2 = new Doppleganger();
       
       Map<Doppleganger, String> map = new HashMap<Doppleganger, String>();
       
       dg1.setHashValue(1);
       dg2.setHashValue(2);
       map.put(dg1, "1");
       map.put(dg2, "2");

       dg1.setHashValue(2);
       out.printf("%d. %d => %s\n", 1, dg1.hashCode(), map.get(dg1));
       out.printf("%d. %d => %s\n", 2, dg2.hashCode(), map.get(dg2));
       
       // TreeMap requires its Key implement Comparable 
       map = new TreeMap<Doppleganger, String>(); 
       
       dg1.setHashValue(1);
       dg2.setHashValue(2);
       map.put(dg1, "1");
       map.put(dg2, "2");

       dg1.setHashValue(2);
       out.printf("%d. %d => %s\n", 3, dg1.hashCode(), map.get(dg1));
       out.printf("%d. %d => %s\n", 4, dg2.hashCode(), map.get(dg2));
    }
}
C:\src\java>java Doppleganger
1. 2 => null
2. 2 => 2
3. 2 => 1
4. 2 => 1

C:\src\java>