在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

虽然s1s2的内容相同,但是它们在内存中的地址不同,因此它们的哈希值也不同。在实际使用中,这可能会导致一些问题,比如无法正确识别集合中的重复元素。

如何重新实现hashCode()方法

要重新实现hashCode()方法,我们需要结合对象的属性值来计算哈希码,以便让具有相同属性值的对象具有相同的哈希码。一般来说,可以采用以下步骤:

  1. 把对象的非零属性用一个质数(比如31)进行加权,并把它们相加。
  2. 如果属性是布尔型,则使用(f ? 1 : 0) 的形式转换成数值型。
  3. 如果属性是浮点型,则使用Float.floatToIntBits(f)的方式把它们转换成整型。
  4. 如果属性是双精度型,则使用Double.doubleToLongBits(f)的方式把它们转换成长整型,并对其进行异或操作。
  5. 如果属性是数组,则对每个元素进行递归处理。

例如,在一个自定义的Person类中,如果我们想让两个对象在nameage属性都相同的情况下返回相同的哈希码,可以按照以下方式重新实现hashCode()方法:

@Override
public int hashCode() {
int result = 17;
result = 31 * result + name.hashCode();
result = 31 * result + age;
return result;
}

其中,1731都是选定的质数。

注意事项

在重新实现hashCode()方法时,需要牢记以下几点:

  1. 哈希码的计算方式应该尽量均匀分布,这样可以提高哈希表的性能。
  2. 如果两个对象的equals()方法返回true,那么它们的哈希码应该相同。
  3. 如果对象的属性值发生变化,那么它的哈希码也应该随之变化。
  4. 哈希码的计算过程中,应该避免使用可能会发生溢出的操作。
  5. 建议使用自动生成的hashCode()方法,例如Eclipse和IntelliJ IDEA都支持自动生成hashCode()equals()方法的功能。

总结

重新实现hashCode()方法可以提高哈希表的效率,使得具有相同属性值的对象具有相同的哈希码。要实现hashCode()方法,需要按照一定的步骤进行计算,并考虑到一些细节问题。在实际开发中,建议使用自动生成的hashCode()方法。

重新实现hashCode()方法的更多相关文章

  1. 为什么要重写hashcode() 方法

    Java中的集合(Collection)有两类,一类是List,再有一类是Set. 前者集合内的元素是有序的,元素可以重复:后者元素无序,但元素不可重复. 那么我们怎么判断两个元素是否重复呢? 这就是 ...

  2. Java基础知识点2:hashCode()方法

    hashCode()方法基本实现 hashCode方法是Java的Object类所定义的几个基本方法之一.我们可以深入到Object类的源码中去查看: public native int hashCo ...

  3. 浅谈Java中的hashcode方法

    哈希表这个数据结构想必大多数人都不陌生,而且在很多地方都会利用到hash表来提高查找效率.在Java的Object类中有一个方法: 1 public native int hashCode(); 根据 ...

  4. java hashCode方法返回值

    hashCode 是和内存地址相关的一个整数. HashCode只是在需要用到哈希算法的数据结构中才有用 用途是为了方便快速地查找对象: HashMap 是根据键对象的 HashCode 来进行快速查 ...

  5. 为什么重写equals时必须重写hashCode方法?

    原文地址:http://www.cnblogs.com/shenliang123/archive/2012/04/16/2452206.html 首先我们先来看下String类的源码:可以发现Stri ...

  6. Java中的equals和hashCode方法

    本文转载自:Java中的equals和hashCode方法详解 Java中的equals方法和hashCode方法是Object中的,所以每个对象都是有这两个方法的,有时候我们需要实现特定需求,可能要 ...

  7. java的HashCode方法

    总的来说,Java中的集合(Collection)有两类,一类是List,再有一类是Set. 前者集合内的元素是有序的,元素可以重复: 后者元素无序,但元素不可重复. 要想保证元素不重复,可两个元素是 ...

  8. Java中hashCode()方法以及HashMap()中hash()方法

    Java的Object类中有一个hashCode()方法: public final native Class<?> getClass(); public native int hashC ...

  9. java中hashCode方法与equals方法的用法总结

    首先,想要明白hashCode的作用,必须要先知道Java中的集合. 总的来说,Java中的集合(Collection)有两类,一类是List,再有一类是Set. 前者集合内的元素是有序的,元素可以重 ...

  10. Java提高篇——equals()与hashCode()方法详解

    java.lang.Object类中有两个非常重要的方法: 1 2 public boolean equals(Object obj) public int hashCode() Object类是类继 ...

随机推荐

  1. 盒子模型和CSS背景和列表

    盒子模型(1)宽度-width:长度值 | 百分比 | auto-max-width:长度值 | 百分比 | auto-min-width:长度值 | 百分比 | auto(2)高度-height:长 ...

  2. 9.15 2020 实验 2:Mininet 实验——拓扑的命令脚本生成

    一.实验目的 掌握 Mininet 的自定义拓扑生成方法:命令行创建.Python 脚本编写   二.实验任务 通过使用命令行创建.Python 脚本编写生成拓扑,熟悉 Mininet 的基本功能. ...

  3. Spring日志与SpringBoot日志

    本篇意为说明Spring默认日志实现与SpringBoot默认日志实现. 1.日志 在这之前,我们应该先了解一些日志框架. 具体可以看我这篇随笔:https://www.cnblogs.com/dai ...

  4. CAS无锁机制

    1. 背景 传统Synchronized锁:悲观,如果没有获取到锁的情况下,会让当前线程变为阻塞的状态,释放CPU执行权,效率非常低. 乐观锁(自旋):本质上没有锁,没有死锁现象,而且效率比较高,不会 ...

  5. DFS专题1

    例题一 39.组合总和 给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target ,找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 , ...

  6. cookies、session、token

    cookies 当登录的时候这个set-cookies就是把cookies的数据保存到了客户端的application/cookies中 session 表示为会话,存放在服务端,当用户登录,服务器就 ...

  7. arp 基本功能

    地址解析协议(英语:Address Resolution Protocol,缩写:ARP)是一个通过解析网络层地址来找寻数据链路层地址的网络传输协议,它在IPv4中极其重要.ARP最初在1982年的R ...

  8. NX 二次开发 多个功能集成一个DLL的方法

    用C++做NX二次开发,一个功能建一个工程,管理起来很不方便,在网上找了些资料学习,成功的把多个功能做到一个工程里(多功能集成到一个DLL). 1.首先要了解外挂的菜单文件的基础,要实现多个功能集合在 ...

  9. CF1732A Bestie

    思路 观察数据\(n \le 20\) 直接暴力. 我们直接算所有数的\(GCD\),然后枚举\(1\)~\(n\)的每一个数要不要选,然后选的话,就把原来的\(GCD\)和当前枚举的数\(GCD\) ...

  10. mmdetection加载ndarray数据,并训练

    1.构造coco数据集,file_name为具体的ndarray文件名,类名的改变和class_num的配置和之前一样.保存的npy文件是归一化之后的结果 2.修改数据加载代码,将 2.修改网络输入i ...