重新实现hashCode()方法
在Java中,为了让对象在集合中能够更高效地进行查找和比较,我们通常需要重写对象的equals()
和hashCode()
方法。其中,equals()
方法用于比较两个对象是否相等,而hashCode()
方法则用于返回对象哈希值,供集合类使用。
默认情况下,Java会根据每个对象的内存地址来计算哈希值,因此如果两个对象在内存中的位置不同,它们的哈希值也会不同。但是,在实际开发中,我们可能需要比较的是对象的属性值而不是内存地址,这时就需要自己来实现hashCode()
方法了。
为什么需要重新实现hashCode()方法
虽然默认实现的hashCode()
方法可以满足基本的哈希表需求,但是它有一个很大的问题:它只是返回对象的内存地址的哈希码,这意味着两个内容完全相同的对象在哈希表中还是会被认为是不同的对象,这样就会浪费大量的空间和时间。例如:
String s1 = new String("hello");
String s2 = new String("hello");
System.out.println(s1.hashCode()); // 输出 99162322
System.out.println(s2.hashCode()); // 输出 99162322
虽然s1
和s2
的内容相同,但是它们在内存中的地址不同,因此它们的哈希值也不同。在实际使用中,这可能会导致一些问题,比如无法正确识别集合中的重复元素。
如何重新实现hashCode()方法
要重新实现hashCode()
方法,我们需要结合对象的属性值来计算哈希码,以便让具有相同属性值的对象具有相同的哈希码。一般来说,可以采用以下步骤:
- 把对象的非零属性用一个质数(比如31)进行加权,并把它们相加。
- 如果属性是布尔型,则使用
(f ? 1 : 0)
的形式转换成数值型。 - 如果属性是浮点型,则使用
Float.floatToIntBits(f)
的方式把它们转换成整型。 - 如果属性是双精度型,则使用
Double.doubleToLongBits(f)
的方式把它们转换成长整型,并对其进行异或操作。 - 如果属性是数组,则对每个元素进行递归处理。
例如,在一个自定义的Person
类中,如果我们想让两个对象在name
和age
属性都相同的情况下返回相同的哈希码,可以按照以下方式重新实现hashCode()
方法:
@Override
public int hashCode() {
int result = 17;
result = 31 * result + name.hashCode();
result = 31 * result + age;
return result;
}
其中,17
和31
都是选定的质数。
注意事项
在重新实现hashCode()
方法时,需要牢记以下几点:
- 哈希码的计算方式应该尽量均匀分布,这样可以提高哈希表的性能。
- 如果两个对象的
equals()
方法返回true
,那么它们的哈希码应该相同。 - 如果对象的属性值发生变化,那么它的哈希码也应该随之变化。
- 哈希码的计算过程中,应该避免使用可能会发生溢出的操作。
- 建议使用自动生成的
hashCode()
方法,例如Eclipse和IntelliJ IDEA都支持自动生成hashCode()
和equals()
方法的功能。
总结
重新实现hashCode()
方法可以提高哈希表的效率,使得具有相同属性值的对象具有相同的哈希码。要实现hashCode()
方法,需要按照一定的步骤进行计算,并考虑到一些细节问题。在实际开发中,建议使用自动生成的hashCode()
方法。
重新实现hashCode()方法的更多相关文章
- 为什么要重写hashcode() 方法
Java中的集合(Collection)有两类,一类是List,再有一类是Set. 前者集合内的元素是有序的,元素可以重复:后者元素无序,但元素不可重复. 那么我们怎么判断两个元素是否重复呢? 这就是 ...
- Java基础知识点2:hashCode()方法
hashCode()方法基本实现 hashCode方法是Java的Object类所定义的几个基本方法之一.我们可以深入到Object类的源码中去查看: public native int hashCo ...
- 浅谈Java中的hashcode方法
哈希表这个数据结构想必大多数人都不陌生,而且在很多地方都会利用到hash表来提高查找效率.在Java的Object类中有一个方法: 1 public native int hashCode(); 根据 ...
- java hashCode方法返回值
hashCode 是和内存地址相关的一个整数. HashCode只是在需要用到哈希算法的数据结构中才有用 用途是为了方便快速地查找对象: HashMap 是根据键对象的 HashCode 来进行快速查 ...
- 为什么重写equals时必须重写hashCode方法?
原文地址:http://www.cnblogs.com/shenliang123/archive/2012/04/16/2452206.html 首先我们先来看下String类的源码:可以发现Stri ...
- Java中的equals和hashCode方法
本文转载自:Java中的equals和hashCode方法详解 Java中的equals方法和hashCode方法是Object中的,所以每个对象都是有这两个方法的,有时候我们需要实现特定需求,可能要 ...
- java的HashCode方法
总的来说,Java中的集合(Collection)有两类,一类是List,再有一类是Set. 前者集合内的元素是有序的,元素可以重复: 后者元素无序,但元素不可重复. 要想保证元素不重复,可两个元素是 ...
- Java中hashCode()方法以及HashMap()中hash()方法
Java的Object类中有一个hashCode()方法: public final native Class<?> getClass(); public native int hashC ...
- java中hashCode方法与equals方法的用法总结
首先,想要明白hashCode的作用,必须要先知道Java中的集合. 总的来说,Java中的集合(Collection)有两类,一类是List,再有一类是Set. 前者集合内的元素是有序的,元素可以重 ...
- Java提高篇——equals()与hashCode()方法详解
java.lang.Object类中有两个非常重要的方法: 1 2 public boolean equals(Object obj) public int hashCode() Object类是类继 ...
随机推荐
- 服务器安装node
卸载步骤[未安装请忽略] 1.卸载npm sudo npm uninstall npm -g 2.卸载node yum remove nodejs npm -y 安装步骤 1.下载 wget http ...
- 【搭建】【转】搭建 yum仓库
https://blog.csdn.net/wuxingge/article/details/100761637 3.2 服务端部署 1)安装软件程序(createrepo) yum install ...
- MySQL日期date型和int型互换的方法
一.date型换int型 SELECT UNIX_TIMESTAMP('2017-9-22 13:54:45') 二.int型转date型 SELECT FROM_UNIXTIME(150605968 ...
- C语言中字符数组的赋值和复制
/*C中,字符串,即字符数组的赋值与字符变量.常量.变量的赋值是不同的.初学者总会犯错误. 常见错误如下: 1.定义的时候直接用字符串赋值 char a[10]; char a[10]="h ...
- 关于如何在IDEA里面配置好Git和Github的相关步骤详解
配置Git 1.File->settings 然后选择其中的Version Control: 接着选择其中的Git选项: 2.将文本框内容定位到本地下载git路径下面 然后点击右边的Test测试 ...
- Python练习--简单练习(一看就能写出来的代码)
两数之和 数字的阶乘 求圆的面积 (输入半径,求解圆的面积) 求区间内所有素数的和 求前N个数字的平方和
- Java笔记第十二弹
Lambda表达式的标准格式 三要素:形式参数.箭头.代码块 格式:(形式参数)->(代码块) 形式参数:如果有多个参数,参数之间用逗号隔开:如果没有参数,留空即可 ->代表指向动作 La ...
- Spring:现代Java开发的必备框架
目录 Spring:现代Java开发的必备框架 Spring创建bean的生命周期以及对应的接口和注解 Spring使用三级缓存解决循环依赖的原理 Spring使用三级缓存创建bean的过程 Spri ...
- 基于深度学习的智能PCB板缺陷检测系统(Python+清新界面+数据集)
摘要:智能PCB板缺陷检测系统用于智能检测工业印刷电路板(PCB)常见缺陷,自动化标注.记录和保存缺陷位置和类型,以辅助电路板的质检.本文详细介绍智能PCB板缺陷检测系统,在介绍算法原理的同时,给出P ...
- Spring 注解整理
更多内容,前往IT-BLOG 一.核心容器 [1]@Configuration:告诉 Spring 这是一个配置类(配置类=配置文件)[2]@Bean:给容器中注册一个 Bean :类型为返回值类型, ...