为什么重写equals必须重写hashCode的基础分析

1.我们先来了解下原生的equals和hashCode代码

  原生equals:它判断的是两个对象是否相等

  原生hashCode值:它是根据内存地址换算出来的一个整数类型的值

2.至于为什么要重写equals和hashCode?

  当然为了满足我们具体的业务需求啦,毕竟我们不一定只比较对象相等嘛

3.做一个超简单小案例来理解下(包名不规范,切勿模仿);

(1)创建一个Student类,不重写equals和hashCode

package 重写equal必须重写hashcode;

public class Student {
public String id; //学生的id
public String name; //学生的名字 public Student() {
super();
// TODO Auto-generated constructor stub
} public String toString() {
return id + ":" + name;
} public Student(String id, String name) {
super();
this.id = id;
this.name = name;
} }

  (2)new一个hashSet,分别添加三个student

package 重写equal必须重写hashcode;

import java.util.HashSet;

public class Test {

	//学生ID和姓名都相同我们视为重复
public static void main(String[] args) {
HashSet hs = new HashSet();
hs.add(new Student("001","小明"));
hs.add(new Student("002","小花"));
hs.add(new Student("002","小花"));
System.out.println(hs);
}
}

  (3)运行结果如下:

(4)我们可以看到,信息出现了重复;new的对象不同生成的hashCode值不同,所以hashSet会把三个Student对象当作不同的对象。

2.接下来我们重写equals而不重写hashCode

(1)重写equals后代码如下:

package 重写equal必须重写hashcode;

public class Student {
public String id; //学生的id
public String name; //学生的名字 public Student() {
super();
// TODO Auto-generated constructor stub
} public String toString() {
return id + ":" + name;
} public Student(String id, String name) {
super();
this.id = id;
this.name = name;
} public boolean equals(Object obj) {
if(this == obj) { //判断是否是同一对象
return true; //同一类型返回true(跟自己比较)
}
if(getClass()!=obj.getClass()) { //判断是否为同一类型
return false; //不是同类型返回false(类型不同肯定为不同的对象)
}
Student stu = (Student)obj; //强制转换成Student类型
boolean result = this.id.equals(stu.id); //判断ID是否相等
return result; //返回判断结果
}
}

 (2)现在我们运行下,结果如下图:

(3)可以发现重复的信息没有删除掉,可以判断添加Student对象没有调用equals方法,而是根据hashCode值的不同,hashSet就认为三个对象不相等。

3.最后我们重写equals和hashCode;

(1)重写hashCode;

package 重写equal必须重写hashcode;

public class Student {
public String id; //学生的id
public String name; //学生的名字 public Student() {
super();
// TODO Auto-generated constructor stub
} public String toString() {
return id + ":" + name;
} public Student(String id, String name) {
super();
this.id = id;
this.name = name;
} public boolean equals(Object obj) {
if(this == obj) { //判断是否是同一对象
return true; //同一类型返回true(跟自己比较)
}
if(getClass()!=obj.getClass()) { //判断是否为同一类型
return false; //不是同类型返回false(类型不同肯定为不同的对象)
}
Student stu = (Student)obj; //强制转换成Student类型
boolean result = this.id.equals(stu.id); //判断ID是否相等
return result; //返回判断结果
} public int hashCode() { //重写hashCode
return id.hashCode(); //返回ID属性的哈希值
}
}

 (2)运行结果如下:

(3)是不是就把重复的信息移除了呢?哈哈

如果有不妥之处,请各位大佬多多包涵,这些也是个人的理解

如果你有补充,欢迎留下你的意见在评论区!

为什么重写equals必须重写hoshCode的基础分析的更多相关文章

  1. 为什么重写equals还要重写hashcode??

    equals和hashcode是object类下一个重要的方法,而object类是所有类的父类,所以所有的类都有这两个方法 equals和hashcode间的关系: 1.如果两个对象相同(即equal ...

  2. 为什么重写equals必须重写hashCode

    目录 equals常见面试题 为什么要重写equals 重写equals不重写hashCode会存在什么问题 总结 equals常见面试题 在开始聊之前,我们先看几个常见的面试题,看看你能不能都回答上 ...

  3. JAVA 重写equals和重写hashCode

    面试官可能会问你:“你重写过 hashcode 和 equals 么,为什么重写equals时必须重写hashCode方法?” 首先你需要了解: hashCode()的作用是获取哈希码(散列码) 它实 ...

  4. 【Java基础】重写equals需要重写hashcode

    Object里的equals用来比较两个对象的相等性,一般情况下,当重写这个方法时,通常有必要也重写hashcode,以维护hashcode方法的常规协定,或者说这是JDK的规范,该协定声明相等对象必 ...

  5. 为什么重写equals还要重写hashcode

    参考回答: HashMap中,如果要比较key是否相等,要同时使用这两个函数!因为自定义的类的hashcode()方法继承于Object类,其hashcode码为默认的内存地址,这样即便有相同含义的两 ...

  6. 谈谈HashSet的存储原理及为什么重写equals必须重写hashcode方法

    HashSet的存储原理: 1.将要传入的数据根据系统的hash算法得到一个hash值: 2.根据hash值可以得出该数据在hash表中的位置: 3.判断该位置上是否有值,没有值则把数据插入进来:如果 ...

  7. 关于重写equals同时重写hashcode

    1.Object中equals方法和hashcode public boolean equals(Object obj) { return (this == obj); } public native ...

  8. 为什么重写equals()就要重写hashcode()

    阿里巴巴开发规范 只要重写 equals,就必须重写 hashCode 因为 Set 存储的是不重复的对象,依据 hashCode 和 equals 进行判断,所以 Set 存储的对象必须重写这两个方 ...

  9. 为什么重写equals()必须重写hashCode()

    主要原因是因为hashCode是用对象的内部地址转换成一个整数的,而equals比较得是两个对象,或者是两个对象的内容 如果你重写了equals,而保留hashCode的实现不变,那么很可能两个对象明 ...

随机推荐

  1. Mongodb关于查询返回指定字段的方法记录

    //通常指定字段由前端传入后台,例如params 前端以逗号分隔 //后端获取字段后操作如下: Query query = new Query(); if (params != null) { Str ...

  2. 游戏设计模式——Unity对象池

    对象池这个名字听起来很玄乎,其实就是将一系列需要反复创建和销毁的对象存储在一个看不到的地方,下次用同样的东西时往这里取,类似于一个存放备用物质的仓库. 它的好处就是避免了反复实例化个体的运算,能减少大 ...

  3. jdk1.8源码阅读

    一.java.lang java的基础类 1.object 所有类的爸爸 registerNatives() Class<?> getClass():返回运行时的类 int hashCod ...

  4. toString(),String.valueOf,(String)在处理空对象时的区别

    public static void main(String[] args) { Map<String,Object> map = new HashMap<>(); map.p ...

  5. (七十三)c#Winform自定义控件-资源加载窗体

    前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. GitHub:https://github.com/kwwwvagaa/NetWinformControl 码云:ht ...

  6. Java图片处理:ico格式转 PNG/JPG等格式

    一. 什么是ico图标? ico是一种图标格式,大量应用于网站,各个软件的logo或图标展示. 我们在进入某个网站或网页,它们上方标题左侧各自都带有logo图标. 这就是favicon.ico图标,它 ...

  7. WebApi简介

    简单创建.NET Core WebApi:https://www.cnblogs.com/yanbigfeg/p/9197375.html 登陆验证四种方式:https://www.cnblogs.c ...

  8. CentOS 8 正式发布

    转载请注明:文章转载自 OSCHINA 社区 [http://www.oschina.net] 本文地址:https://www.oschina.net/news/110111/centos-8-re ...

  9. 解决CentOS6.x或RedHat Linux 6.x版本不能通过System eth0以固定IP访问外网的问题

    当你在VMware Workstation Pro中,打开从别人那里克隆来的系统,或者是开启迁移后的虚拟机系统时,VMware将会提示你:此虚拟机可能已被移动或 复制.为了配置特定的管理和网络功能.V ...

  10. 初识PE文件结构

    前言 目前网络上有关PE文件结构说明的文章太多了,自己的这篇文章只是单纯的记录自己对PE文件结构的学习.理解和总结. 基础概念 PE(Portable Executable:可移植的执行体)是Win3 ...