天天看点

深入理解hashCode()和equals()方法的关系。

1.首先要明白hashCode()和equals()方法的作用。

hashCode():根据对象的内存地址计算出哈希值
           
/**
返回一个对象的散列码,这个方法有利于哈希表,例如HashMap
Returns a hash code value for the object. This method is supported for the benefit of hash tables such as those provided by java.util.HashMap. 
*/
    public native int hashCode();
           
equals():根据内存地址,对比两个对象是否相等,有一个java基础问题,equals和 == 的区别?
           

2.为什么要有hashCode()和equals()方法呢?

Java中的Collection有两类,一类是List,一类是Set。

深入理解hashCode()和equals()方法的关系。
  • List内的元素是有序的,元素可以重复。Set元素无序,但元素不可重复。要想保证元素不重复,应该依据什么来判断呢?你可能会想:这容易呀,直接调用元素对象的 equals() 方法进行比较不就行了吗?如果容器中的存储的对象数量较少,这确实是个好主意,但是如果容器中存放的对象达到了一定的规模,要调用容器中所有对象的 equals() 方法和新元素进行比较,就不是一件容易的事情了。 equals() 方法的比较逻辑简单无比,总的来说也是一个时间复杂度为 O(n) 的操作,效率成为大问题。
  • 这时候hashCode的作用就体现了,散列表的查询效率是O(1),每个对象都自带有 hashCode(),这个 hashCode 将会用作散列表哈希函数的输入,hashCode 经过哈希函数计算后得到哈希值,新对象会根据哈希值,存储到相应的内存的单元。这样一来,每一个要对比的对象只需要对比哈希值就能够完成,加入新元素时,这个新加入的元素已经存在,需要另作处理:覆盖掉原来的元素(key)或舍弃。

3.数据量更大了,又出问题了!!!

  • 当输入样本量足够大时,不相同的输入是会产生相同输出的,也就是形成哈希冲突(看hashcode的原理吧)。这时候该怎么办呢?
  • ==hashCode()和equals()方法结合使用!==当出现两个对象hashCode相等时,再调用equals方法对比,如果相等,则认为他们是同一个对象。这样既提高了效率,又能保证准确性。
  • 那么有面试题“两个对象的 hashCdoe() 相同,它的 equals() 方法一定要返回 true,对吗?”,错误!!理由如上