原文在在下的博客上.今天在看Thinking in java第三版中的LinkedHashMap部分,对其中几段代码很茫然,代码如下:public class Groundhog ...{
  protected int number;
  public Groundhog(int n) ...{ number = n; }
  public String toString() ...{
    return "Groundhog #" + number;
  }
} public class Prediction ...{
  private boolean shadow = Math.random() > 0.5;
  public String toString() ...{
    if(shadow)
      return "Six more weeks of Winter! ";
    else
      return "Early Spring! ";
  }
}import java.lang.reflect.*;public class SpringDetector ...{           //这个类的部分代码本人进行了一些修改,不足之处望指正
 
  public static void detectSpring(Class groundHogClass) throws Exception ...{
    Constructor ghog = groundHogClass.getConstructor(new Class[] ...{int.class});
   
    Map<Object,Prediction> map = new HashMap<Object,Prediction>();  //这里的泛型是否有更好的表达                                                                                                                                     //方式?
    for(int i = 0; i < 10; i++)
      map.put(ghog.newInstance( new Integer(i) ), new Prediction());
         
    System.out.println("map = " + map + " ");
    System.out.println("");    Groundhog gh = (Groundhog)ghog.newInstance(new Integer(3));
    //这段原代码是: Groundhog gh = (Groundhog)ghog.newInstance(new Object[] { new Integer(3) });
    //不知有什么实际用途,我修改後结果依然一样。
    System.out.println("Looking up prediction for " + gh);
    if(map.containsKey(gh))
      System.out.println(map.get(gh));
    else
      System.out.println("Key not found: " + gh);
  }
  public static void main(String[] args) throws Exception ...{
    detectSpring(Groundhog.class);
  }
}摘录其中部分关键代码:
Groundhog gh = (Groundhog)ghog.newInstance(new Integer(3));
   
    System.out.println("Looking up prediction for " + gh);
    if(map.containsKey(gh))
      System.out.println(map.get(gh));
    else
      System.out.println("Key not found: " + gh);输出结果是“Key not found:  Groundhog #3”
我对此不解,明明都是Groundhog #3,为什么不包含这个Key?
然后查API,containsKey部分涉及到了Object的hashCode()和equals(),但却不知hashCode()究竟为何物,
于是google了一下,找到了一篇hashCode的相关文章,链接如下:
http://student.zjzk.cn/course_ware/data_structure/web/chazhao/chazhao9.4.1.htm大概有了点朦朦胧胧理解后,在继续查API
Object中containsKey的定义.boolean containsKey(Object key)    如果此映射包含指定键的映射关系,则返回 true。更正式地说,当且仅当此映射包含键 k 的以下映射关系时才返回 true:(key==null ? k==null : key.equals(k))。(最多只能有一个这样的映射关系)。从这可以看出需要用到equals(),而Object中的equals规定很严格,必须地址相同,而hashCode的返回的不同引用的地址是不同的,即使是相同的对象.这是从
http://student.zjzk.cn/course_ware/data_structure/web/chazhao/chazhao9.4.1.htm这篇文章中感受到的,
    所以要想达到期待的map.containsKey(gh)返回true的效果,就必须覆盖hashCode()和equals()
所以这下Bruceeckel修改後的代码就好理解了
    public class Groundhog2 extends Groundhog ......{
      public Groundhog2(int n) ......{ super(n); }
      public int hashCode() ......{ return number; }
      public boolean equals(Object o) ......{
        return (o instanceof Groundhog2)
          && (number == ((Groundhog2)o).number);
      }
    }    import java.util.*;    public class SpringDetector2 ......{      public static void main(String[] args) throws Exception ......{
        SpringDetector.detectSpring(Groundhog2.class);
      }
    }
    覆盖後的equals方法忽略了地址的比较,所以得到了理想的结果.本人文笔不佳,文章结构不够理想,叙述不够清楚,还请见谅