欢迎您访问广东某某机械环保科有限公司网站,公司主营某某机械、某某设备、某某模具等产品!
全国咨询热线: 400-123-4567

新闻资讯

哈希游戏| 哈希游戏平台| 哈希游戏APP

HAXIYOUXI-HAXIYOUXIPINGTAI-HAXIYOUXIAPP

哈希游戏- 哈希游戏平台- 官方网站【原创】不重写equals和hashcode难道就不行吗?

作者:小编2026-03-09 17:18:24

  哈希游戏- 哈希游戏平台- 哈希游戏官方网站

哈希游戏- 哈希游戏平台- 哈希游戏官方网站【原创】不重写equals和hashcode难道就不行吗?

  我们都知道在一个长度为n的线性表中,存放着无序的数字,那么如果我们想要找到一个特定的数字,就不得不通过从头到尾依次遍历来查找,这样的时间复杂度是n/2。我们再来看Hash表。在Hash表里,存放在其中的数据和它的存储位置是用Hash函数关联的,它的时间复杂度接近于1,代价相当小,下面对Hash算法做个简单的介绍。为了方便说明,我们先假设一个长度为11的线性表作为Hash表,并假设一个比较简单的Hash函数是x ^ 2 % 5。如果我们想要把数字5放入表中,那么我们首先对5代入Hash函数计算一下:5 ^ 2 % 5 = 0,所以我们就把5存放到索引号为0的这个位置。当我们反过来从中找5这个元素时,我们可以先通过Hash函数算出5的索引号,然后直接去对应索引号中就可以找到了,这样会显得十分的方便。

  一般来讲,我们应该根据实际中的具体业务来重写equals()方法用于比较不同的对象,但是我们在重写equals()方法的同时最好也要重写一下hashCode()方法。当然,如果没有重写hashCode()方法,程序依然可以执行,只不过以后用起来可能会存在bug。一般一个类的对象如果会存储在HashTable,HashSet,HashMap等散列存储结构中,如果重写equals()后没有重写hashCode(),很可能会因为存储了两个equals相等的数据而导致存储数据的不唯一性。如果确定不会存储在这些散列结构中,则可以不重写hashCode()。但是个人觉得还是重写比较好一点,万一后期要存储在这些结构中呢,况且重写了hashCode()也不会降低性能,因为在线性结构(如ArrayList)中是不会调用hashCode(),所以重写了也不要紧,保证有备无患嘛。

  结果分析:当我们重写equals()方法以后,equals()方法的运行结果为true。而没有重写hashCode()方法时,hashCode()的返回值默认是以对象的内存地址作为返回值的,因此两个对象的哈希值一定不同。这时候的set长度依然为2,说明HashSet认为这是两个不同对象。因为HashSet、HashMap、HashTable这类的散列存储结构,按照java的机制会先调用hashCode()方法来确定元素所在的“桶”,然后再调用equals()方法来确定该桶内是否已经存在该元素。因此,在先调用hashCode()方法返回值不一致时,Set会把元素存储到不同的“桶”内,所以Set的长度仍为2。

  我们可以看到在调用remove方法的时候,会先使用对象的hashCode值去找到这个对象,然后进行删除。那对于我们的例子来说,Set的remove操作同样是先调用hashCode()方法找到元素所在的“桶”,再调用equals()方法确定“桶”内是否存在该元素。我们修改了stu2的学号id,导致其hashCode值发生了变化,而这个hashCode值又参与了运算,就好比是stu2根据原先的hashCode值是在“桶1”中,执行remove操作时会到现在的hashCode值的“桶5”中寻找,这样肯定是找不到的,所以删除也不会成功,set长度同样不会有变化。因此,如果我们将对象的属性值参与了hashCode的运算中,在进行删除的时候,就不能对其属性值进行修改,否则会出现严重的内存泄露问题。