Java 8注释描述
- 这个方法返回一个对象的哈希码值 (hash code)
- 支持这个方法有利于散列表 (hash tables),比如在HashMap提供的散列表
- hashCode方法概要
- 在任何时候,假如用来对比对象的方法equals没有被修改,那么对同一个对象来说,多次调用hashCode方法应返回相同的整数。这个整数不需要保持一致在同一个表达式的多次调用上
- 若两个对象是相同的(通过equals方法),那么这两个对象调用hashCode方法将返回相同的整数结果
- 若两个对象是不同的(通过equals方法),那么这两个对象调用hashCode方法不一定需要返回不同的结果
- 然而,程序员应该意识到对于不相同的对象,返回不相同的整数结果,可能会提高散列表 (hash tables) 的性能
- 在一般情况下,hashCode方法确实会为不同的对象返回不同的整数(这个通常是将对象的内存地址转换为整数来实现的,但Java编程语言不需要这种实现技术)
参考Object类hashCode相关文章
方法分析
- 虽然Java 8中注释说明hashCode方法的返回值跟对象内存地址有关,但实际上,在java 6和7中,它是随机数生成的数字,而在java 8中,它是基于线程有关的随机数和三个确定值确定的(Marsaglia’s xorshift scheme随机数算法)
- 所以,hashCode方法的返回值与对象的内存地址无关
- 其次,咱们可以通过JVM启动参数
-XX:hashCode=指定生成方式序号
来改变它的生成方式
为什么重新定义equals方法,就需要重新定义hashCode方法
- 首先,Java中只是建议重新定义equals方法时,重新定义hashCode方法;实际上,是否需要重新定义hashCode还是取决于具体的使用场景,不是强制必须的
- 其次,Java中在不仅仅是两个方法重写,最好能够保证当两个对象equals相等时,它们的hashCode也相等
- 那么,假设不重新定义hashCode又会发生什么呢?如:
- 在HashMap中,其底层的数据结构采用的是:数组 + 链表(或红黑树)
- 在分配key在数组的哪个位置时,就需要根据key的hashCode来进行分配
- 当为两个对象 (equals方法结果为false) 分配位置时,若它们的hashCode相同,那么就会被分配到数组的同一个位置上,形成链表(长度小于8)
- 此时就会影响到HashMap的查询性能
- 注意:这只是一种场景,其中的影响绝不仅仅是这一种
- 结论:这不是必须的,但是最好能够遵循Java的关于重写的建议