面试记录之为什么 Java 的基础数据类型要重写 hashCode 方法

面试被刨根问底,所以记录一下
介绍什么是 hash ,存在哪,为什么 Java 的基础类型数据要重写 hashCode() 方法 。

一、什么是 hash

Hash值(哈希值)是指通过一种特定的算法,将任意长度的数据映射为固定长度的数据序列,这个数据序列就是哈希值。哈希值可以用于数据的唯一性校验、数据加密、数据压缩、快速查找等领域。

在 Java 官方文档中可以看到,所有类都隐式地继承自Object类。在Java 8官方文档中有以下一段话:
“All classes in Java are derived from the Object class. If a Class declaration does not have an extends clause, it is implicitly assumed to extend the Object class.”

通过继承 Object 类所有对象都有一个 hashCode 方法,如果没重写就是用的 Object 里的默认方法。用于计算对象的哈希值。hashCode() 返回的哈希值是一个 int 类型的值。在使用 Java 集合类中的哈希表(HashMap、HashSet等)时,哈希值被用于确定对象在表中的位置,以提高查找效率。因此,实现 hashCode 方法的正确性和效率对于Java程序的性能和正确性都至关重要。

二、hash 值存在哪

哈希码值实际上是由对象的内存地址转换而来的,也就是说,不同对象的哈希码值不同。在内存中,对象的哈希码值通常被存储在对象的对象头中,这个对象头位于对象内存的最前面,包含了一些对象的元数据,如哈希码值、锁状态等等。因此,当我们调用一个对象的 hashCode() 方法时,实际上就是返回这个对象对象头中存储的哈希码值。

但是并不是所有的对象都是把哈希码放在对象头里,比如基础类型和与之对应的包装类

Java中的基础数据类型(primitive data types)包括byte、short、int、long、float、double、char、boolean等,它们是不可变的,没有实现对象,因此没有对象的哈希码。

这个时候肯定会想到 Integer、String 这些对象,Java提供了自动装箱和自动拆箱机制,这样基本数据类型就可以在需要使用对象的情况下,自动地转换为对象。

那每次 new 一个 String,他的地址值可是不一样的。为什么最终哈希码是一样的?
当然是重写了 hashCode() 方法 以 String 对象为例,他就是按值去算哈希码的。
String 的

三、为什么基础数据类型的包装类要重写 hashCode 方法

主要有 2 点:

1、为了提升效率

因为基本数据类型是按值传递的,因此相同值的变量在内存中也具有相同的地址,可以视为同一个对象。如果使用对象的内存地址作为哈希值,则每次比较时需要比较对象的内存地址,这样会增加哈希表的查找时间,因为需要遍历整个链表或树结构以查找元素。而如果使用对象的内容作为哈希值,则可以直接比较内容,这样可以减少比较时间,并且也避免了哈希冲突的问题

2、设计如此

String 的常量池(String Pool)是 Java 中一种优化字符串的机制。在 Java 中,如果创建了一个字符串对象,它首先会在字符串池中查找是否存在该字符串,如果存在,则返回池中的实例,否则创建新的实例并放入池中。使用字符串池,可以避免创建重复的字符串对象,从而减少内存占用。


String Pool 也是使用字符串的内容来判断字符串是否存在的。当一个新的字符串被创建时,它会首先在字符串池中查找是否已经存在相同内容的字符串,如果已经存在则返回池中的字符串对象,否则创建新的字符串对象并添加到池中。因此,如果String类不重写hashCode()方法,字符串池也无法正常工作。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值