hashCode与equals深度剖析与源码详解

hashCode与equals深度剖析与源码详解

TOC

1.Set特点

(1)元素无顺序 (2)元素不能有重复的。

2.Object类equals方法的特点

(1)自反:前提object不为空,x.equals(x)应该为true. (2)对称性:x.equals(y)为true,那么y.equals(x)也为true; (3)传递性:x.equals(y)为true,并且y.equals(z)为true,那么x.equals(z)也应该为true; (4)一致性:x.equals(y)为true,那么x.equals(y)的第二次,第三次,第n次调用也应该为true,前提是比较之间没有修改x也没有修改y. (5)对于非空引用x,x.equals(null)返回false;

2.1注意

(1)Object的equals()方法就是用==来比较的。 (2)当我们要Override equals()这个方法的时候,也要同时去Override hashcode()这个方法。

3.关于Object类hashCode方法的特点

(1)在java应用的一次执行过程当中,对于同一个对象的hashCode方法的多次调用,它们应该返回同样的值(前提是该对象的信息没有发生变化)。 (2)对于两个对象来说,如果使用equals方法比较返回true,那么这两个对象的hashCode值也一定是相同的。 (3)对于两个对象来说,如果使用equals方法比较返回false,那么这两个对象的hashCode不要求一定不同(可以相同,可以不同),但是如果不同则可以提高应用的性能。 (4)对于Object类来说,不同的Object 对象的hashCode值是不同的(Object类的hashCode值表示对象的地址)。

4.HashSet的调用过程

(1)当使用HashSet时,hashCode()方法就会得到调用,判断已经存储在集合中的对象的hash code值是否与增加的对象的hashcode值一致,如果不一致,则直接加进去,如果一致再进行equals方法的比较,equals方法如果返回true,表示对象已经加进去了,就不会再增加新对象了,否则就加进去。

5.总结

(1)对于一个集合来说,判断一个对象到底能不能放到集合里面,这是通过hash code与equals方法来共同去完成的。

(2)如果对于我们自己的一个类,要想让它内容一样,比如说两个人,只要两个人名字一样,它的内容就一样,这个时候,两个张三就不要放在一个集合里面。

重写hashcode方法,重写equals方法,因为这两个方法都是Object类定义的,而且这两个方法又是密切相关的,所以在绝大多数情况下,我们只要重写了hashcode方法,我们就要同时重写equals方法。反过来也是一样的。重写了equals方法,也要重写hashcode方法。

(3)如果我们重写equals方法,那么也 要重写hashCode方法,反之亦然。

java 复制代码
package com.javase.hashset;

import java.util.HashSet;
/**
 * 不使用Object类提供的hashCode方法与equalse方法,
 * 使用自己实现的hashCode方法与equals方法判断两个对象的内容是否相同
 * 重写hashCode方法与equals方法
 * @author x_xiongjie
 *
 */
public class SetTest3 {
	@SuppressWarnings("unchecked")
	public static void main(String[] args) {
		HashSet set = new HashSet();
		Student s1 = new Student("zhangsan");
		Student s2 = new Student("zhangsan");
		set.add(s1);
		set.add(s2);
		System.out.println(set);
		
	}
}

class Student{
	private String name;
	
	public Student(String name){
		this.name = name;
	}
	//借助于name的hash code来代表类本身的hash code.
	@Override
	public int hashCode() {
		return this.name.hashCode();
	}
	
	@Override
	public boolean equals(Object obj) {
		if(obj == this){
			return true;
		}
		//如果obj不为空,并且是当前类的实例。
		if(obj != null && obj instanceof Student){
			Student s = (Student) obj;
			if(name.equals(s.name)){
				return true;
			}
		}
		return false;
	}
}

(1)在实际开发过程中,判断对象能不能放到集合里面,大多数情况下都是根据内容来决定的,而不是根据地址来决定的。

(2)实际实现的时候,hashCode与equals都是通过内容来实现的,这个内容来如何体现,就是通过类的成员变量去体现的,两个对象内容到底是不是一样,就是通过成员变更去体现的,数据表示对象的状态。 )实际实现的时候,hashCode与equals都是通过内容来实现的,这个内容来如何体现,就是通过类的成员变量去体现的,两个对象内容到底是不是一样,就是通过成员变更去体现的,数据表示对象的状态。

相关推荐
前鼻音太阳熊1 小时前
【MES系统】MES为什么需要SSE?从设备实时监控谈Spring Boot流式推送设计
java·spring boot·后端
Lhappy嘻嘻1 小时前
网络初识|基础入门:局域网广域网、IP 端口、TCP/IP 五层模型与封装解封装全过程
java·开发语言·网络·笔记·网络协议·tcp/ip
Java面试题总结1 小时前
区间树:反向映射的前置数据结构
java·前端·数据结构
尚早立志2 小时前
六)Spring Boot 源码研读之prepareContext 准备上下文
java·spring boot·后端·spring
Lhappy嘻嘻10 小时前
Java IO|File 文件操作 + 字节流 / 字符流完整笔记 + 递归删除文件实战
java·笔记·php
伊玛目的门徒10 小时前
试用leetcode之典中典 二数之和问题
java·算法·leetcode
懒鸟一枚13 小时前
深入理解 Linux 内存、Swap 交换分区与分页机制的关系
java·linux·数据库
我命由我1234514 小时前
执行 Gradle 指令报错,无法将“grep”项识别为 cmdlet、函数、脚本文件或可运行程序的名称
android·java·java-ee·android studio·android jetpack·android-studio·android runtime
考虑考虑15 小时前
Sentinel安装
java·后端·微服务
凤凰院凶涛QAQ16 小时前
《Java版数据结构 & 集合类剖析》栈与队列:“push/pop 是栈的灵魂,offer/poll 是队列的骨架——四组 API,两种人生”
java·开发语言·数据结构