【源码分析】Object中的“鸡肋“函数

2023-11-04 05:44

本文主要是介绍【源码分析】Object中的“鸡肋“函数,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

java中的“鸡肋”代码

返回对象的散列码值。支持此方法是为了使用哈希表,例如java.util.HashMap提供的哈希表。

  • 具体使用可以看【源码分析】HashMap真源码阅读

hashCode的总契约是:

  • 在Java应用程序的执行过程中,只要在同一对象上多次调用hashCode方法,hashCode方法必须始终返回相同的整数,前提是对象上用于相等比较的信息没有被修改。该整数不必在应用程序的一次执行与另一次执行之间保持一致。
  • 如果根据equals(Object)方法两个对象相等,那么对这两个对象中的每一个调用hashCode方法必须产生相同的整数结果。
  • 根据equals(Object)方法,如果两个对象不相等,则不要求对这两个对象中的每一个调用hashCode方法必须产生不同的整数结果。然而,程序员应该意识到,为不相等的对象生成不同的整数结果可能会提高哈希表的性能。

在合理可行的情况下,由Object类定义的hashCode方法确实为不同的对象返回不同的整数。(这通常通过将对象的内部地址转换为整数来实现,但是Java™编程语言不需要这种实现技术。)

  • 同一对象调用多次调用hashCode方法必须始终返回相同的整数,且整数不必在应用程序的一次执行与另一次执行之间保持一致
  • 前提是对象上用于相等比较的信息没有被修改,这句我的理解是equals方法按照注释上实现。
  • equals 两对象相等,hashCode方法必须产生相同的整数结果
  • equals 两对象不相等,hashCode方法必须产生不相同的整数结果

注:理论上不同值计算hash是可以相同的,作者也解释为什么一定要hashcode方法生成结果不同:为不相等的对象生成不同的整数结果可能会提高哈希表的性能。

回忆一下Hash函数设计的基本要求(完美满足,Hashtable,HashMap可以直接用了):

  • 散列函数计算得到的散列值是一个非负整数;
  • 如果 key1 = key2,那 hash(key1) == hash(key2);
  • 如果 key1 ≠ key2,那 hash(key1) ≠ hash(key2)。(往往这个条件很难办到,key不同可能出现相同的散列值,于是出现散列冲突)
public native int hashCode();

指示其他对象是否“等于”此对象。
equals方法在非空对象引用上实现等价关系:

  • 它是自反的:对于任何非空的引用值x, x.x equals(x)应该返回true。
  • 它是对称的:对于任何非空引用值x和y,当且仅当y.equals(x)返回true时,x.equals(y)应该返回true。
  • 它是可传递的:对于任何非空引用值x, y和z,如果x.equals(y)返回true并且y.equals(z)返回true,则x.equals(z)应该返回true。
  • 它是一致的:对于任何非空引用值x和y,如果不修改对象上的相等比较中使用的信息,则多次调用x.equals(y)一致地返回true或一致地返回false。
  • 对于任何非空的引用值x, x.equals(null)应该返回false。

Object类的equals方法在对象上实现了最具区别性的可能的等价关系;也就是说,对于任何非空引用值x和y,当且仅当x和y引用同一对象(x == y的值为true)时,此方法返回true。

  • 当且仅当x和y引用同一对象为true,因此,重写次方法第一步就应该实现if (this == object) { return true; }

请注意,每当覆盖hashCode方法时,通常都需要覆盖该方法,以便维护hashCode方法的一般契约,该契约规定相等的对象必须具有相等的哈希码。

public boolean equals(Object obj) {return (this == obj);
}

hashCode和equals小结

hashCode实现约定:

  • equals 两对象相等,hashCode方法必须产生相同的整数结果
  • equals 两对象不相等,hashCode方法必须产生不相同的整数结果

注意:

  • 每当重写hashCode方法时,通常都需要重写equals
  • == 在基本数据类型:值内容, 引用类型时:地址
  • equals 重写:值内容 , equals不重写:地址

不同类型hashCode和equals对比

这篇关于【源码分析】Object中的“鸡肋“函数的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/343641

相关文章

Springboot中分析SQL性能的两种方式详解

《Springboot中分析SQL性能的两种方式详解》文章介绍了SQL性能分析的两种方式:MyBatis-Plus性能分析插件和p6spy框架,MyBatis-Plus插件配置简单,适用于开发和测试环... 目录SQL性能分析的两种方式:功能介绍实现方式:实现步骤:SQL性能分析的两种方式:功能介绍记录

Python itertools中accumulate函数用法及使用运用详细讲解

《Pythonitertools中accumulate函数用法及使用运用详细讲解》:本文主要介绍Python的itertools库中的accumulate函数,该函数可以计算累积和或通过指定函数... 目录1.1前言:1.2定义:1.3衍生用法:1.3Leetcode的实际运用:总结 1.1前言:本文将详

最长公共子序列问题的深度分析与Java实现方式

《最长公共子序列问题的深度分析与Java实现方式》本文详细介绍了最长公共子序列(LCS)问题,包括其概念、暴力解法、动态规划解法,并提供了Java代码实现,暴力解法虽然简单,但在大数据处理中效率较低,... 目录最长公共子序列问题概述问题理解与示例分析暴力解法思路与示例代码动态规划解法DP 表的构建与意义动

轻松上手MYSQL之JSON函数实现高效数据查询与操作

《轻松上手MYSQL之JSON函数实现高效数据查询与操作》:本文主要介绍轻松上手MYSQL之JSON函数实现高效数据查询与操作的相关资料,MySQL提供了多个JSON函数,用于处理和查询JSON数... 目录一、jsON_EXTRACT 提取指定数据二、JSON_UNQUOTE 取消双引号三、JSON_KE

MySQL数据库函数之JSON_EXTRACT示例代码

《MySQL数据库函数之JSON_EXTRACT示例代码》:本文主要介绍MySQL数据库函数之JSON_EXTRACT的相关资料,JSON_EXTRACT()函数用于从JSON文档中提取值,支持对... 目录前言基本语法路径表达式示例示例 1: 提取简单值示例 2: 提取嵌套值示例 3: 提取数组中的值注意

C#使用DeepSeek API实现自然语言处理,文本分类和情感分析

《C#使用DeepSeekAPI实现自然语言处理,文本分类和情感分析》在C#中使用DeepSeekAPI可以实现多种功能,例如自然语言处理、文本分类、情感分析等,本文主要为大家介绍了具体实现步骤,... 目录准备工作文本生成文本分类问答系统代码生成翻译功能文本摘要文本校对图像描述生成总结在C#中使用Deep

Java function函数式接口的使用方法与实例

《Javafunction函数式接口的使用方法与实例》:本文主要介绍Javafunction函数式接口的使用方法与实例,函数式接口如一支未完成的诗篇,用Lambda表达式作韵脚,将代码的机械美感... 目录引言-当代码遇见诗性一、函数式接口的生物学解构1.1 函数式接口的基因密码1.2 六大核心接口的形态学

Java中Object类的常用方法小结

《Java中Object类的常用方法小结》JavaObject类是所有类的父类,位于java.lang包中,本文为大家整理了一些Object类的常用方法,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1. public boolean equals(Object obj)2. public int ha

Go中sync.Once源码的深度讲解

《Go中sync.Once源码的深度讲解》sync.Once是Go语言标准库中的一个同步原语,用于确保某个操作只执行一次,本文将从源码出发为大家详细介绍一下sync.Once的具体使用,x希望对大家有... 目录概念简单示例源码解读总结概念sync.Once是Go语言标准库中的一个同步原语,用于确保某个操

Redis主从/哨兵机制原理分析

《Redis主从/哨兵机制原理分析》本文介绍了Redis的主从复制和哨兵机制,主从复制实现了数据的热备份和负载均衡,而哨兵机制可以监控Redis集群,实现自动故障转移,哨兵机制通过监控、下线、选举和故... 目录一、主从复制1.1 什么是主从复制1.2 主从复制的作用1.3 主从复制原理1.3.1 全量复制