java,php,asp.net,linux,javascript,mysql,mssql,oracle,编程

equals,hashcode

转载请注明:http://www.pmjava.com/Article/ShowInfo.asp?ID=56635

现在也不是非常清楚这两个东东之间的关系,尝试理解,望知道的朋友开示:
  Equals(): 用来比较两个对象的内容是否相等,是Object类提供的一个方法,被所有的类所继承,其源代码是
        public  boolean equals(Object obj) {
            return (this == obj);
        }
 
  Hashcode(): 用来获取对象的hash码,也是object类提供的方法,
  Hash码的引入(以下纯粹是个人理解,错漏之处请朋友们指正):
数据结构中,我们知道用来存储数据的几种常见的结构有,线性表,二叉树等,而通过线性表,二叉树寻找数据需要遍历,如果结构过大,则必会影响效率,由是提出了一种通过对象的关键码与存储地址之间的映射直接找到对象的机制,以便快速查找,这就是hash表的由来,
思路建立了,下一步就是要如何定义这个存储内容的关键字以使码与地址一一对应,由是提供了几种hash算法来取得hash码,可是由于内容的不确定性导致无论哪种算法取得的hash码都不能保证唯一性,
即:不同的内容可能得出相同的hash码,
出现这种情况就是hash冲突,于是又提出了用一些辅助的手段来消除冲突

根据以上的内容,我尝试理解下equals和hashcode的关系:
我们知道,java中的集合是用来存放对象的,在集合中,如果存放的对象很多,比如100万个,那如果采用遍历的方式取出来,效率可想而知,由是,集合(map)的设计者就想到了用hash表的方式来解决这种获取效率的问题,具体如下:
在往map中put对象的时候,先通过hashcode()方法获取key的hash码,然后把这个码和key建立对应关系,get的时候,同样获取key的hash码,通过hash码与key的映射可以直接找到key,进而取出value,当然以上只是理想的情况,因为有hash冲突,就可能导致不同的key而得到的hash码是相同的,这个时候消除这个冲突的方式就是equals()方法,即get对象时,先取key的hashcode,可能有多个,但是,只取内容和要取的key相等的键,这就保证了唯一性,定位到了键,也就定位到了値,
就好比[引用网友的话]:
带有编号的猪圈里有多少猪
这个编号就是hashcode
你要比较猪是否相同 通过hashcode(及猪圈编号)直接定位到一个猪圈

 

1.何时需要重写equals()

  当一个类有自己特有的“逻辑相等”概念(不同于对象身份的概念)。

  2.设计equals()

  [1]使用instanceof操作符检查“实参是否为正确的类型”。

  [2]对于类中的每一个“关键域”,检查实参中的域与当前对象中对应的域值。

  [2.1]对于非float和double类型的原语类型域,使用==比较;

  [2.2]对于对象引用域,递归调用equals方法;

  [2.3]对于float域,使用Float.floatToIntBits(afloat)转换为int,再使用==比较;

  [2.4]对于double域,使用Double.doubleToLongBits(adouble) 转换为int,再使用==比较;

  [2.5]对于数组域,调用Arrays.equals方法。

  3.当改写equals()的时候,总是要改写hashCode()

  根据一个类的equals方法(改写后),两个截然不同的实例有可能在逻辑上是相等的,但是,根据Object.hashCode方法,它们仅仅是两个对象。因此,违反了“相等的对象必须具有相等的散列码”。

  4.设计hashCode()

  [1]把某个非零常数值,例如17,保存在int变量result中;

  [2]对于对象中每一个关键域f(指equals方法中考虑的每一个域):

  [2.1]boolean型,计算(f ? 0 : 1);

  [2.2]byte,char,short型,计算(int);

  [2.3]long型,计算(int) (f ^ (f>>>32));

  [2.4]float型,计算Float.floatToIntBits(afloat);

  [2.5]double型,计算Double.doubleToLongBits(adouble)得到一个long,再执行[2.3];

  [2.6]对象引用,递归调用它的hashCode方法;

  [2.7]数组域,对其中每个元素调用它的hashCode方法。


  [3]将上面计算得到的散列码保存到int变量c,然后执行 result=37*result+c;

  [4]返回result。

posted on 2009-06-10 21:56 rrong_m 阅读(279) 评论(0)  编辑  收藏

<2024年11月>
272829303112
3456789
10111213141516
17181920212223
24252627282930
1234567

导航

统计

常用链接

随笔档案

文章分类

文章档案

java编程

搜索

积分与排名

最新评论

阅读排行榜

评论排行榜