首页 > 其他分享 >Object.hashCode() 详解

Object.hashCode() 详解

时间:2023-12-25 18:02:07浏览次数:32  
标签:对象 Object equals hashCode 详解 哈希 散列码 方法

在Java编程中,hashCode方法是一个常见而重要的概念。它通常用于哈希表、集合以及一些需要高效检索数据的数据结构中。然而,对于许多开发者来说,hashCode方法可能是一个容易被忽略或者被简单实现的部分。在本文中,我们将深入探讨Java中hashCode的一些思考,以便更好地理解其背后的原理和影响。

hashcode.jpg

hashCode的简介

hashCode 返回的 "散列码" 是指通过哈希算法生成的一个整数,用于标识对象的唯一性。在Java中,hashCode方法被设计用来支持基于哈希的集合类,如HashMap、HashSet等,以及其他需要快速检索数据的数据结构。

hashCode的意义

  • 快速检索

散列码的主要作用是提高数据结构的检索效率。在哈希表中,通过散列码可以迅速定位到存储数据的位置,而不需要遍历整个数据集。这对于大规模数据集的快速检索非常重要,能够使得检索操作的时间复杂度接近常数级别。

  • 哈希集合性能

在使用哈希集合(如HashSet)时,散列码决定了元素在集合中的存储位置。如果不同的对象具有相同的散列码,就会发生哈希冲突,需要通过其他手段解决,如链地址法或开放寻址法。因此,好的散列码设计能够最小化哈希冲突,提高哈希集合的性能。

  • equals方法辅助

hashCode方法与equals方法是相关联的。在Java中,根据对象相等性的定义,如果两个对象相等(equals方法返回true),那么它们的散列码应该相等。这一关系有助于在哈希集合中正确地比较和存储对象。

  • 分布均匀

散列码的设计应尽量使得不同的对象生成不同的散列码,以减少哈希冲突的可能性。这需要考虑到对象的各个属性,确保它们都对最终的散列码有贡献,避免简单地依赖于某一个属性。

重写 hashCode 方法

为什么要重写 hashCode 方法

Object类中提供的默认实现是与当前线程有关的随机数和其他三个固定值进行xorshift运算后的结果数。这种默认实现在实际应用中可能并不总是满足需要,特别是当我们需要基于对象的内容来计算哈希码时。

源码如下:

public native int hashCode();

如何重写hashCode方法

在自定义类中,如果希望基于对象的内容生成哈希码,通常需要重写hashCode()方法。为了简化哈希码的计算,我们可以使用Objects工具类,提供了hash方法,可以接受多个参数,并根据它们生成一个合并后的哈希码。

示例如下:

@Data
public class UrlEntity {
    private Integer id;
    private String url;

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        UrlEntity entity = (UrlEntity) o;
        return Objects.equals(id, entity.id) && Objects.equals(url, entity.url);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id, url);
    }

哈希冲突

由于哈希码是一个有限位数的整数,不同的对象可能生成相同的哈希码,这就是哈希冲突。为了最小化哈希冲突的概率,好的哈希码应该能够均匀分布。在实际应用中,可以通过一些技巧和算法来提高哈希码的质量,减少冲突的可能性。

比如如下代码:

public static void main(String[] args) {
    String str1 = "3C";
    String str2 = "2b";
    System.out.println("字符串"+str1+"的hashCode值为:"+str1.hashCode());
    System.out.println("字符串"+str2+"的hashCode值为:"+str2.hashCode());
}

运行结果为:

字符串3C的hashCode值为:1648
字符串2b的hashCode值为:1648

不同的对象,却拥有了相同的 hashCode值, 这就是哈希冲突。

为什么重写equals方法时一定要重写hashCode方法

在Java中,equals 方法和 hashCode 方法之间存在一种协定,这个协定规定了如果两个对象根据 equals 方法被认为相等,那么它们的 hashCode 值必须相等。反之亦然,如果两个对象的 hashCode 值相等,它们不一定要相等。

这一规定的原因在于,在使用基于散列的集合类(例如 HashMap、HashSet 等)时,对象的 hashCode 值通常用于确定对象在内部存储结构中的位置。当你在集合中使用对象时,集合会首先检查对象的 hashCode 值,然后再使用 equals 方法来确保这个位置上没有相等的对象。

如果你重写了 equals 方法但没有重写 hashCode 方法,那么可能会导致违反这个协定,即相等的对象具有不同的 hashCode 值。这样的情况会导致在使用散列集合时出现问题,因为相等的对象应该被视为相等,它们应该在集合中占据相同的位置。

总结

在Java中,Object.hashCode()方法在处理集合类和对象比较时发挥着关键作用。了解其原理以及如何正确重写这个方法对于编写高效、正确的代码至关重要。通过理解哈希码的生成方式,我们可以更好地利用Java的集合类,并确保我们的自定义类在使用这些类时能够正确地工作。

标签:对象,Object,equals,hashCode,详解,哈希,散列码,方法
From: https://blog.51cto.com/xiuji/8970768

相关文章

  • Keepalived 高可用详解
    Keepalived详解1、Keepalived介绍​ Keepalived是一个基于VRRP协议来实现LVS服务高可用方案,可以利用其来避免单点故障。一个LVS服务会使用2台服务器运行Keepalived,一台为主服务器MASTER,另一台为备份服务器BACKUP,但是对外表现为一个虚拟IP,主服务器会发送特定的消息给备份服务......
  • C# Task详解
    C#Task详解 推荐几篇写的很好的文章,本文部分转自https://blog.csdn.net/btfireknight/article/details/97766193https://blog.csdn.net/boonya/article/details/80541571https://blog.csdn.net/nacl025/article/details/9163495/1.Task原理这里简要的分析下CLR线程池......
  • 使用WebStack和Laravel打造个人网址导航安装过程问题和详解记录
    前言最近测试了国内推出的多个AI大模型,为了方便记录同时方便推荐给朋友想做个AI工具网址导航。网上开源的项目有很多,最后选中了WebStack和Laravel,但是不知道是否作者长时间不更新了遇到不少问题,解决完记录一下。准备工作,购买云服务器,安装宝塔,解析域名解析等等正文1.登录宝塔创建站......
  • top命令详解
    top命令详解概述toptop是一个常用的命令行工具,用于实时监视系统的进程和系统资源使用情况。它提供了一个动态更新的终端界面,显示了各个进程的CPU使用率、内存占用、进程ID、运行时间等信息。下面是top命令的一些常用选项和功能:显示进程信息:top命令默认显示当前系统中运行的......
  • Web.Config文件详解
    一).Web.Config是以XML文件规范存储,配置文件分为以下格式    1.配置节处理程序声明      特点:位于配置文件的顶部,包含在<configSections>标志中。    2.特定应用程序配置      特点:  位于<appSetting>中。可以定义应用程序的全局常量设置等信息.    ......
  • ({ a: 1, b: 2 }).toString(),为什么输出的是[object Object]?
    在JavaScript中,每个对象都包含一个内部属性[[Class]],表示该对象的类型。这个属性是由JavaScript引擎内部自动设置的,并且不能直接访问。当你调用对象的toString方法时,JavaScript引擎会通过这个属性来确定对象的类型,并将其作为字符串返回。对于大多数JavaScript对象来说,......
  • Unity3D UI帧动画详解
    nity3D是一款非常强大的游戏开发引擎,它提供了丰富的功能和工具,使开发者能够轻松创建各种类型的游戏。其中,UI(UserInterface)是游戏开发中非常重要的一部分,它用于展示游戏中的各种信息和交互元素。在Unity3D中,我们可以使用UI帧动画来创建各种炫酷的UI效果。本文将详细介绍Unity3D中U......
  • Unity3D 中正确调用CUDA程序详解
    Unity3D是一款强大的游戏开发引擎,可以实现各种各样的游戏效果。然而,在某些情况下,使用CPU来处理游戏中的复杂计算任务可能会导致性能瓶颈。为了解决这个问题,我们可以利用CUDA来使用GPU进行并行计算,从而提高游戏的性能。对啦!这里有个游戏开发交流小组里面聚集了一帮热爱学习游戏的......
  • Unity3D UDP传输大文件怎么提高速度详解
    Unity3D是一款强大的游戏开发引擎,但是在处理大文件传输时,往往会遇到速度较慢的问题。本文将详细介绍如何通过使用UDP协议来提高大文件传输的速度,并给出相应的技术详解和代码实现。对啦!这里有个游戏开发交流小组里面聚集了一帮热爱学习游戏的零基础小白,也有一些正在从事游戏开发的......
  • 【Spring教程29】Spring框架实战:从零开始学习SpringMVC 之 服务器响应知识全面详解
    目录1环境准备2响应页面3返回文本数据4响应JSON数据5知识点总结欢迎大家回到《Java教程之Spring30天快速入门》,本教程所有示例均基于Maven实现,如果您对Maven还很陌生,请移步本人的博文《如何在windows11下安装Maven并配置以及IDEA配置Maven环境》,本文的上一篇为《SpringMVC......