您的位置:程序门 -> java -> j2se / 基础类



hashcode(),containskey及equals的一些粗浅体会


[收藏此页] [打印本页]选择字色:背景色:字体:[][][]


hashcode(),containskey及equals的一些粗浅体会
发表于: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方法忽略了地址的比较,所以得到了理想的结果.

本人文笔不佳,文章结构不够理想,叙述不够清楚,还请见谅
发表于:2007-07-07 22:27:471楼 得分:0
本文地址
http://tb.blog.csdn.net/trackback.aspx?postid=1682344,欢迎批评意见
发表于:2007-07-07 23:57:072楼 得分:0
更正博客地址:
http://blog.csdn.net/weiqiyiji/archive/2007/07/07/1682344.aspx
发表于:2007-07-08 11:34:303楼 得分:0
mark。

吃完饭回来看。
发表于:2007-07-08 22:10:444楼 得分:0
up


快速检索

最新资讯
热门点击