原文在在下的博客上.今天在看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方法忽略了地址的比较,所以得到了理想的结果.本人文笔不佳,文章结构不够理想,叙述不够清楚,还请见谅
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方法忽略了地址的比较,所以得到了理想的结果.本人文笔不佳,文章结构不够理想,叙述不够清楚,还请见谅
http://tb.blog.csdn.net/TrackBack.aspx?PostId=1682344,欢迎批评意见
http://blog.csdn.net/weiqiyiji/archive/2007/07/07/1682344.aspx