为什么要重写hashcode()⽅法
Java中的集合(Collection)有两类,⼀类是List,再有⼀类是Set。
前者集合内的元素是有序的,元素可以重复;后者元素⽆序,但元素不可重复。
那么我们怎么判断两个元素是否重复呢?这就是Object.equals⽅法了。
通常想查⼀个集合中是否包含某个对象,就是逐⼀取出每个元素与要查的元素进⾏⽐较,当发现某个元素与要查的对象进⾏equals⽅法⽐较的结果相等时,则停⽌继续查并返回肯定的信息,否则返回否定的信息,如果⼀个集合中有很多元素譬如成千上万的元素,并且没有包含要查的对象时,则意味着你的程序需要从该集合中取出成千上万个元素进⾏逐⼀⽐较才能得到结论,于是,有⼈就发明了⼀种哈希算法来提⾼从集合中查元素的效率,这种⽅式将集合分成若⼲个存储区域,每个对象可以计算出⼀个哈希码,可以将哈希码分组,每组分别对应某个存储区域,根据⼀个对象的哈希码就可以确定该对象应该存储的那个区域.
hashCode⽅法可以这样理解:它返回的就是根据对象的内存地址换算出的⼀个值。这样⼀来,当集合要添加新的元素时,先调⽤这个元素的hashCode⽅法,就⼀下⼦能定位到它应该放置的物理位置上。如果这个位置上没有元素,它就可以直接存储在这个位置上,不⽤再进⾏任何⽐较了;如果这个位置上已经有
元素了,就调⽤它的equals⽅法与新元素进⾏⽐较,相同的话就不存了,不相同就散列其它的地址。这样⼀来实际调⽤equals⽅法的次数就⼤⼤降低了,⼏乎只需要⼀两次。
谈到hashcode()和equals()就不能不说到hashset,hashmap,hashtable中的使⽤,具体是怎样呢,请看如下分析:
Hashset是继承Set接⼝,Set接⼝⼜实现Collection接⼝,这是层次关系。那么hashset是根据什么原理来存取对象的呢?
在hashset中不允许出现重复对象,元素的位置也是不确定的。在hashset中⼜是怎样判定元素是否重复的呢?判断两个对象是否相等的规则是:
.1),判断两个对象的hashCode是否相等
如果不相等,认为两个对象也不相等,完毕,如果相等,转⼊2
.2),判断两个对象⽤equals运算是否相等
如果不相等,认为两个对象也不相等
如果相等,认为两个对象相等(equals()是判断两个对象是否相等的关键)equals()方法
⼩结:
(1)只有类的实例对象要被采⽤哈希算法进⾏存储和检索时,这个类才需要按要求覆盖hashCode⽅法,即使程序可能暂时不会⽤到当前类的hashCode⽅法,但是为它提供⼀个hashCode⽅法也不会有什么不好,没准以后什么时候⼜⽤到这个⽅法了,所以,通常要求hashCode⽅法和equals⽅法⼀并被同时覆盖。
(2)equals()相等的两个对象,hashcode()⼀定相等;equals()不相等的两个对象,却并不能证明他们的hashcode()不相等。换句话
说,equals()⽅法不相等的两个对象,hashcode()有可能相等。反过来:hashcode()不等,⼀定能推出equals()也不等;hashcode()相
等,equals()可能相等,也可能不等。
提⽰:
(1)通常来说,⼀个类的两个实例对象⽤equal⽅法⽐较的结果相等时,它们的哈希码也必须相等,但反之则不成⽴,即equals⽅法⽐较结果不相等的对象可以有相同的哈希码,或者说哈希码相同的两个对象的equal⽅法⽐较的结果可以不等。
(2)当⼀个对象被存储进hashset集合中以后,就不能修改这个对象中的那些参与计算哈希值的字段了,否则,对象修改后的哈希值与最初存储进hashset集合时的哈希值就不同了,这种情况下,即使在contains⽅法使⽤该对象的当前引⽤作为的参数去hashset集合中检索对象,也将返回不到对象的结果,这也会导致⽆法从hashset集合中单独删除当前对象,从⽽造成内存泄露,所谓的内存泄露也就说有⼀个对象不再被使⽤,但它⼀直占有内存空间,没有被释放。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论