大家都知道,equals和hashcode是java.lang.Object类的两个重要的方法,在实际应用中常常需要重写这两个方法,但至于为什么重写这两个方法很多人都搞不明白。

下面我们看下Object类中默认的equals和hashCode方法的实现:

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

  

以上是Object类关于这两个方法的源码,Object类默认的equals比较规则就是比较两个对象的内存地址。而hashcode是本地方法,但实际上,hashcode是根据对象的内存地址经哈希算法得来的。

 import lombok.AllArgsConstructor;
import lombok.Data; /**
* Created by ganbo on 2019/6/17.
*/ @Data
@AllArgsConstructor
public class User {
private Long id;
private String name; @Override
public boolean equals(final Object o) {
if (this == o) return true;
if (!(o instanceof User)) return false;
if (super.equals(o)) return true; final User user = (User) o; if (id != null ? !id.equals(user.id) : user.id != null) return false;
return name != null ? name.equals(user.name) : user.name == null;
} @Override
public int hashCode() {
int result = 1;
result = 31 * result + (id != null ? id.hashCode() : 0);
result = 31 * result + (name != null ? name.hashCode() : 0);
return result;
} }

上面代码展示了重写equals和hashCode方法后的User类,线有如下代码:

     public static void main(String[] args) {
User u1 = new User(1L, "root");
User u2 = new User(1L, "root"); System.out.println(u1.equals(u2));
System.out.println(u1.hashCode() == u2.hashCode());
}

此时u1.equals(u2)一定返回true,假如只重写equals而不重写hashCode,那么User类的hashCode方法默认就是继承父类Object的hashCode方法,由于默认的hashCode方法是根据对象的内存地址

经过hash算法得来的,显然此时u1对象和u2对象的hashCode值不一定相等,这个时候将该对象作为HashMap的key就会出现问题,跟期望的不一致(两个对象equals,却存在MashMap的两个槽上)。

然而重写了equals,且u1.equals(u2)返回true,根据hashcode的规则,两个对象相等其哈希值一定相等,所以矛盾就产生了,因此重写equals一定要重写hashcode,而且从类重写后的hashcode方法中可以看出,

重写后返回的新的哈希值与User的两个属性有关。

以下是关于hashcode的一些规定:

两个对象相等,hashcode一定相等

两个对象不等,hashcode不一定不等

hashcode相等,两个对象不一定相等

hashcode不等,两个对象一定不等

为什么重写equals一定要重写hashCode方法?的更多相关文章

  1. 为什么重写equals时必须重写hashCode方法?(转发+整理)

    为什么重写equals时必须重写hashCode方法? 原文地址:http://www.cnblogs.com/shenliang123/archive/2012/04/16/2452206.html ...

  2. 讲解:为什么重写equals时必须重写hashCode方法

    一 :string类型的==和equals的区别: 结论:"=="是判断两个字符串的内存地址是否相等,equals是比较两个字符串的值是否相等,具体就不做扩展了,有兴趣的同学可以去 ...

  3. 为什么重写equals一定要重写hashCode?

    大家都知道,equals和hashcode是java.lang.Object类的两个重要的方法,在实际应用中常常需要重写这两个方法,但至于为什么重写这两个方法很多人都搞不明白,以下是我的一些个人理解. ...

  4. 为什么重写equals后要重写hashCode

    equals和hashCode的关系 要搞清楚题目中的问题就必须搞明白equals方法和hashCode方法分别是什么,和诞生的原因,当搞明白了这一点其实题目就不算是个问题了,下面我们来探讨分别探讨一 ...

  5. java 中为什么重写 equals 后需要重写 hashCode

    本文为博主原创,未经允许不得转载: 1. equals 和 hashCode 方法之间的关系 这两个方法都是 Object 的方法,意味着 若一个对象在没有重写 这两个方法时,都会默认采用 Objec ...

  6. 编写高质量代码改善C#程序的157个建议——建议12: 重写Equals时也要重写GetHashCode

    建议12: 重写Equals时也要重写GetHashCode 除非考虑到自定义类型会被用作基于散列的集合的键值:否则,不建议重写Equals方法,因为这会带来一系列的问题. 如果编译上一个建议中的Pe ...

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

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

  8. java中为什么重写equals时必须重写hashCode方法?

    在上一篇博文Java中equals和==的区别中介绍了Object类的equals方法,并且也介绍了我们可在重写equals方法,本章我们来说一下为什么重写equals方法的时候也要重写hashCod ...

  9. 重写equals就必须重写hashCode的原理分析

    因为最近在整理Java集合的源码, 所以今天再来谈谈这个古老的话题,因为后面讲HashMap会用到这个知识点, 所以重新梳理下. 如果不被重写(原生Object)的hashCode和equals是什么 ...

随机推荐

  1. Linux 系统管理——账号管理

    一.用户账号管理 1.用户账户概述 用户账户的常见分类: 超级用户:root  uid=0  gid=0  权限最大 普通用户:uid>=500  做一般权限的系统管理,权限有限. 程序用户:1 ...

  2. 51、Spark Streaming之输入DStream和Receiver详解

    输入DStream代表了来自数据源的输入数据流.在之前的wordcount例子中,lines就是一个输入DStream(JavaReceiverInputDStream), 代表了从netcat(nc ...

  3. 基于Linux(中标麒麟)上QT的环境搭建——解决cannot find lGL的问题

    接上一篇,QT在中标麒麟环境安装完成后遇到运行报错的问题 一.问题描述: 在中标麒麟上配置好QT的环境后,新建一个工程,不做其他的任何操作,直接运行都会报cannot find lGL的错误.如图所示 ...

  4. PHP base_convert() 函数

    16进制转8进制 <?php $hex = "E196"; echo base_convert($hex,,); ?> 8进制数转换为10进制数 <?php $o ...

  5. 【POJ3083】Children of the Candy Corn

    本题传送门 本题知识点:深度优先搜索 + 宽度优先搜索 本题题意是求三个路径长度,第一个是一直往左手边走的距离,第二个是一直往右手边走的距离,第三个是最短距离. 第三个很好办,就是一个简单的bfs的模 ...

  6. ICEM-缺口圆柱

    原视频下载地址:https://pan.baidu.com/s/1bpahxd9 密码: bpp7

  7. 微信小程序之网络通信

    关于网络通信,这里我使用的是wx.request,官方代码示例如下: wx.request({ url: 'test.php', //仅为示例,并非真实的接口地址 data: { x: '', y: ...

  8. [转]Windows内存堆内容整理总结

    在系统安全研究中,堆,是一个极其重要的内存区域以及研究的热点.堆,区别于栈区.全局数据区以及代码区,它的主要作用是允许程序在运行时动态地申请某个大小的内存空间.本文将从宏观到微观,简单梳理总结一下Wi ...

  9. jmeter测试 flask 接口请求

    jmeter测试 flask 接口请求 flask的代码如下: #!/usr/bin/env python # -*- coding: utf-8 -*- from flask import Flas ...

  10. Gson字符串编码,字符串转换成图片保存,二进制转换成图片保存

    import java.io.BufferedInputStream; import java.io.ByteArrayInputStream; import java.io.File; import ...