HashCode原理
- 原理
- 概念:
根据一定的规则将与对象相关的信息(比如对象的存储地址,对象的字段等)映射成一个数值,这个数值称作为散列值。
-
- 作用:
主要是保证基于散列的集合,如HashSet、HashMap以及HashTable等,在插入元素时保证元素不可重复,同时为了提高元素的插入删除便利效率而设计;主要是为了查找的便捷性而存在。
-
- 常见类别
- Integer.hashCode()即对应的int值;故equals相等则相等。
- String.equals()是根据具体的内容(实际的字符串),通过特定的算法计算出来的。
- Object.hashCode()是通过对应的地址计算。
- equals方法和hashCode方法
- 在重写equals方法的同时,必须重写hashCode方法
- 设计hashCode()原则
无论何时,对同一个对象调用hashCode()都应该产生同样的值。
如果两个对象根据equals方法比较是相等的,那么两个对象的hashCode方法返回的整数值必须相等。
如果两个对象根据equals方法比较是不等的,则hashCode方法不一定得返回不同的整数。
-
- 应用:哈希表
可以提供快速的插入操作和查找操作。数据的插入删除便利时间复杂度为O(1)
- 使用问题
- 哈希表中只覆盖equals()情况下,造成元素的重复性和本身设置的不符。
如在散列表中,当为了使满足某种条件的两个对象相等(例在属性相等则忽略地址均认为属于同一元素)情况下,重写了equsals()方法,而未重写hashCode()方法。但是散列表判断元素是否相同,是先通过hashCode一致后才equals()比较,则会出现bug。即要想保证元素的唯一性,必须同时覆盖hashCode和equals才行。
-
- 内存泄露:
在哈希表中元素添加之后,不能修改其与hashCode有关的信息(如用户自定义的hashCode()方法,该方法的值和具体的属性有关),防止remove等操作因元素桶的变化而失效的同时,在集合中进行大量的元素添加后修改值再进行remove移除,导致内存泄露。
![](https://i-blog.csdnimg.cn/blog_migrate/aa157c03f06625522c59fd08588cef4b.png)
- 总结:
- Hashcode是为了提高元素在哈希表中的插入删除便利效率而设计的
- 为了保证程序的严谨性,必须同时覆盖hashCode和equals
- 在哈希表中元素添加之后,不能修改其与hashCode有关的信息,防止remove操作失效,发生内存泄露
- 如果两个对象根据equals方法比较是相等的,那么两个对象的hashCode方法返回的整数值必须相等。
- 哈希算法
是将数据依特定算法直接指定到一个地址上。
这样一来,当集合要添加新的元素时,先调用这个元素的HashCode方法,就一下子能定位到它应该放置的物理位置上。
(1)如果这个位置上没有元素,它就可以直接存储在这个位置上,不用再进行任何比较了;
(2)如果这个位置上已经有元素了,就调用它的equals方法与新元素进行比较,相同的话就不存了;
(3)不相同的话,也就是发生了Hash key相同导致冲突的情况,那么就在这个Hash key的地方产生一个链表,将所有产生相同HashCode的对象放到这个单链表上去,串在一起(很少出现)。这样一来实际调用equals方法的次数就大大降低了,几乎只需要一两次。