hashCode(),containsKey及equals的一些粗浅体会

今天在看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方法忽略了地址的比较,所以得到了理想的结果.
本人文笔不佳,文章结构不够理想,叙述不够清楚,还请见谅

你可能感兴趣的:(hashCode(),containsKey及equals的一些粗浅体会)