| 发表于:2007-07-07 22:24:31 楼主 |
原文在在下的博客上. 今天在看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方法忽略了地址的比较,所以得到了理想的结果. 本人文笔不佳,文章结构不够理想,叙述不够清楚,还请见谅 |
|
|
|
|