`

关于hashcode与equal函数

    博客分类:
  • java
 
阅读更多

hashcode:独一无二地代表了一个对象,并且通过hashcode可以找到这个对象。(比价不准确的说法)

在java.lang.Object的规范中,对hasCode有如下的约定:
 1 在一个应用程序执行期间,如果一个对象的equals方法做比较所用到的信息没有被修改的话,那么对该对象调用多次hashCode方法,它必须返回相同的整数。在同一程序的多次执行过程中,这个整数方法可以不同。
2 如果两个对象根据equals方法是相等的,那么调用这两个对象的hashCode方法必须产生同样的整数结果。
3 如果两个对象根据equals方法是不相等的,那么调用这两个对象的hashCode方法,不要求产生不同的整数结果。

只是为了维护 hashCode 方法的常规协定,才要求用equals比较的两个对象的hashCode相同.

equals()和hashCode()都来自java.lang.Object.你当然可以重写.

比如a.equals(b).仅当a的内存地址相等时,才返回true.当然如String等类已经对这个方法进行了重写,比较的就不再是内存地址了.

hashCode()的值也是与内存地址相关的.所以仅当内存地址相等时,hashCode才相等.同样很多类也重写了这个方法,还是以String为例:
public int hashCode() {
int h = hash;
if (h == 0) {
int off = offset;
char val[] = value;
int len = count;

for (int i = 0; i < len; i++) {
h = 31*h + val[off++];
}
hash = h;
}
return h;
}
就不在与内存地址相关了.这样做是为了保证用equals比较返回为true的两个对象,他们的hashCode是相同的.

所以一般重写equals的时候都会重写hashCode().

当然,这个相当于一个约定,一个协议.你不这么做并不会错.

 

hash code、equals和“==”三者的关系

1.如果是基本变量,没有hashcode和equals方法,基本变量的比较方式就只有==;

2.如果是变量,由于在java中所有变量定义都是一个指向实际存储的一个句柄(你可以理解为c++中的指针),在这里==是比较句柄的地址(你可以理解 为指针的存储地址),而不是句柄指向的实际内存中的内容,如果要比较实际内存中的内容,那就要用equals方法,但是!!!

如果是你自己定义的一个类,比较自定义类用equals和==是一样的,都是比较句柄地址,因为自定义的类是继承于object,而object中的equals就是用==来实现的,你可以看源码。

那为什么我们用的String等等类型equals是比较实际内容呢,是因为String等常用类已经重写了object中的equals方法,让equals来比较实际内容,你也可以看源码。

3. hashcode
在一般的应用中你不需要了解hashcode的用法,但当你用到hashmap,hashset等集合类时要注意下hashcode。

你想通过一个object的key来拿hashmap的value,hashmap的工作方法是,通过你传入的object的hashcode在内存中找 地址,当找到这个地址后再通过equals方法来比较这个地址中的内容是否和你原来放进去的一样,一样就取出value。

所以这里要匹配2部分,hashcode和equals
但假如说你new一个object作为key去拿value是永远得不到结果的,因为每次new一个object,这个object的hashcode是 永远不同的,所以我们要重写hashcode,你可以令你的hashcode是object中的一个恒量,这样永远可以通过你的object的 hashcode来找到key的地址,然后你要重写你的equals方法,使内存中的内容也相等。。。

== 是比较地址是否相等,JAVA中声明变量都是引用嘛,不同的引用,可能指向同一个地址。

equals 是比较值是否相等。

分享到:
评论

相关推荐

    面试官瞬间就饱了,重写equals函数,需要重写hashCode函数吗?

    在Java编程语言中,`equals()` 和 `hashCode()` 方法是对象的基本组成部分,它们与对象的比较和哈希表(如 `HashMap`)的操作密切相关。在面试中,面试官提出的问题直指这两个方法的重要关联。 首先,`equals()` ...

    解析Java对象的equals()和hashCode()的使用

     在Java语言中,equals()和hashCode()两个函数的使用是紧密配合的,你要是自己设计其中一个,要设计另外一个。在多数情况 下,这两个函数是不用考虑的,直接使用它们的默认设计可以了。但是在一些情况下,这两个...

    c#的日期函数使用方法

    ### C#中的日期函数使用方法 C# 是一种强大的面向对象的编程语言,它提供了丰富的类库支持,其中 `DateTime` 类是处理日期和时间的关键类之一。在本篇文章中,我们将详细介绍 C# 中 `DateTime` 类的一些常用方法...

    Java-Reflection-and-Object-Comparison-in-Java:Java Reflection创建适当的对象,覆盖equal和hashCode方法

    空构造函数定义公共方法void setIntValue(int iIn){...}定义公共方法void setStringValue(String sIn){...}按照以下方式设计Java类:2个私有数据成员double DoubleValue ; int IntValue; 空构造函数定义公共...

    学生集合排序

    // 构造函数、getters和setters... @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null || getClass() != obj.getClass()) return false; Student student = ...

    Findbugs缺陷等级对照表.pdf

    * 43B:类中定义了 hashCode() 方法,但是没有重写 java.lang.Object 中的 hashCode() 方法 * 44C:类中定义了 tostring() 方法,但是没有重写 java.lang.Object 中的 tostring() 方法 * 45C:某些方法名只有大小写...

    Kotlin极简教程

    #### 2.2 函数与方法 函数在Kotlin中使用fun关键字定义,可以有默认参数、可变参数等特性: ```kotlin fun greet(name: String) { println("Hello, $name!") } greet("World") // 调用函数 ``` #### 2.3 类与...

    通过构造函数实例化对象的方法

    * @Data 编译后会自动生成set、get、无惨构造、equals、canEqual、hashCode、toString方法 */ @Data public class Person { private String name; private int age; public Person(String name){ this.name = ...

    8张图解java.docx

    它们必须被捕获,或者在函数中声明为抛出该异常。例如,IOException 是一个受检查异常,它必须被捕获或声明。 集合类的层次结构 集合类的层次结构图中,Collections 和 Collection 是两个不同的接口。Collection ...

    八张图深度理解Java特性

    红色部分为受检查异常,它们必须被捕获,或者在函数中声明为抛出该异常。 图 4:集合类的层次结构 Java 中的集合类有多种,图 4 展示了集合类的层次结构。需要注意的是,Collections 和 Collection 的区别,...

    lombok插件

    Lombok通过注解的方式,自动处理getter、setter、构造函数、equals、hashCode以及toString等方法,避免手动编写这些重复的代码。 在标题提到的压缩包中,包含了三个不同版本的Lombok插件:0.19-2017.3、0.19-2018.1...

    java笔试题

    #### 三、HashCode与Equal之间的关系 1. 如果两个对象通过`equals()`方法比较认为是相等的,那么它们的`hashCode()`值也应该是相同的。这是因为`equals()`方法用于比较对象内容是否相同,而`hashCode()`方法返回的...

    Java中Equals使用方法汇总

    本文将深入探讨`equals`方法的使用方法、重写注意事项以及与`hashCode`方法的关系。 ### Q1. 何时应该重写`equals`方法? 在需要比较对象的值而不是引用时,应重写`equals`方法。默认情况下,`equals`方法使用`==`...

    麻省理工18年春软件构造课程阅读15-相等-1

    例如,一个`Duration`类可能表示一段持续时间,它的表示契约是`mins`和`secs`都是非负整数,而抽象函数(AF)将这些值转换为分钟和秒的时间跨度。 相等性通常有两种:引用相等(referential equality)和对象相等...

    Kotlin基础教程.pdf

    它们自动提供了 `equals()`、`hashCode()`、`toString()` 等方法。 ```kotlin data class User(val name: String, val age: Int) fun main() { val user = User("John", 30) println(user) val updatedUser = ...

    sample:核心 Java 示例

    样本 核心 Java 示例 1.Comparable Vs Comparator 2.Equal() & HashCode() 契约 3.Runtime Class 4.Uninstantiable Class 5.Immutable Class

    Object-C语言教程&案例&相关项目资源

    - 通常与`isEqual:`方法一起重写,以确保一致性。 #### 3. `equals` 方法 ```objective-c - (BOOL)isEqual:(id)object; ``` - **描述**:此方法用于判断两个对象是否相等,默认情况下,比较的是对象的内存地址。...

    程序员面试题

    - 如果类实现了 `hashCode()` 方法,则建议同时重写 `equals()` 方法,以保持一致性。 #### 3. forward 和 redirect 的区别 **forward:** - 使用服务器端转发,客户端浏览器的URL不会发生变化。 - 效率较高,因为...

Global site tag (gtag.js) - Google Analytics