深入理解hashCode
1、hashCode的概念
(1)hashCode方法是Object类的方法,在Java里所有类都默认继承Object类,即所有类都有hashCode方法。
(2)hashCode是jdk根据对象的存储地址算出来的一个int数字,即对象的哈希码值,代表了该对象在内存中的存储地址。
2、hashCode的作用
2.1、hashCode查找的快捷性
hashCode的存在主要是用于查找的快捷性,如HashTable、HashMap等,hashCode用来在散列存储结构中确定对象的存储地址(是存储地址)。
2.2、HashSet不允许重复是如何实现的
比如,大家都知道HashSet是不允许重复的,HashSet有100个元素了,这时再add一个新元素。
(1)如果没有hashCode
就需要迭代100次,调用100次equals方法来判断该HashSet里是否已经存在这个新添加的元素。可想而知,效率是很低的。
(2)如果有hashCode
向HashSet添加一个新元素时,HashSet首先会调用hashCode方法,这样就可以定位到它的存储位置,若该处没有元素,则直接保存。如果该处已经有元素存在,就调用equals判断这两个元素内容是否相同,相同则不存,不同则散列到其它位置。这样处理,当我们向HashSet插入大量元素的时候就可以大大减少调用equals方法的次数,提高了效率。
2.3、HashSet集合和hashCode方法的代码示例
import java.util.HashSet;
public class Person {
private int id;
private String name;
public Person(int id, String name) {
super();
this.id = id;
this.name = name;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + id;
result = prime * result + ((name == null) ? 0 : name.hashCode());
//用于查看hashCode方法什么时候被调用,以及被调用的次数
System.out.println("hashCode被调用, hashCode=" + result);
return result;
}
@Override
public boolean equals(Object obj) {
//用于查看equals方法什么时候被调用,以及被调用的次数
System.out.println( "equals被调用了" );
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Person other = (Person) obj;
if (id != other.id)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
public static void main(String[] args) {
HashSet<Person> personHashSet = new HashSet<Person>();
personHashSet.add(new Person(1, "张三"));
personHashSet.add(new Person(2, "李四"));
personHashSet.add(new Person(1, "张三"));
System.out.println("personHashSet的长度是" + personHashSet.size());
}
}
hashCode被调用, hashCode=775881
hashCode被调用, hashCode=843084
hashCode被调用, hashCode=775881
equals被调用了
personHashSet的长度是2
每次向personHashSet添加一个Person时,都会调用hashCode方法,这样就可以直接定位该Person所存储的位置,若该处没有其它Person,则直接保存。若该处已经有Person存在,就调用equals方法来判断两个Person是否相同,相同则不存,不同则散列到其他位置。示例代码里,向personHashSet添加新元素时,hashCode方法无论如何都会被调用,所以hashCode方法被调用了三次。第1个Person和第3个Person的hashCode是相同的,添加第3个Person时才会去调用equals方法,所以equals方法被调用了一次。equals为true,相同则不存,所以personHashSet的长度是2。
(注:HashSet更详细的解读,会出现在本人后面的博文中,这里就不喧宾夺主本文的主题了。)
3、hashCode和equals的关系
(1)equals相等,hashCode一定相等。
(2)equals方法被重写,那么hashCode方法也应该被重写,并且产生hashCode使用的对象(类里面的属性),一定要和equals方法中使用的一致。
(3)hashCode相等,equals不一定相等。只能说明这两个对象在散列存储结构里(如Hashtable)“存放在同一个蓝子里”。
深入理解hashCode的更多相关文章
- 深入理解 hashcode 和 hash 算法
深入理解 hashcode 和 hash 算法 2017年12月30日 23:06:07 阅读数:5197 标签: hashhashmaphashcode二进制 更多 个人分类: jdk-源码 ht ...
- HashCode的理解
一.hashcode是什么 要理解hashcode首先要理解hash表这个概念 1. 哈希表 hash表也称散列表(Hash table),是根据关键码值(Key value)而直接进行访问的数据结构 ...
- Java中hashcode的理解
Java中hashcode的理解 原文链接http://blog.csdn.net/chinayuan/article/details/3345559 怎样理解hashCode的作用: 以 java. ...
- java中的hashcode
hashcode的作用 对于包含容器类型的程序设计语言来说,基本上都会涉及到hashCode.在Java中也一样,hashCode方法的主要作用是为了配合基于散列的集合一起正常运行,这样的散列集合包括 ...
- Java 集合系列 14 hashCode
java 集合系列目录: Java 集合系列 01 总体框架 Java 集合系列 02 Collection架构 Java 集合系列 03 ArrayList详细介绍(源码解析)和使用示例 Java ...
- 正确重写hashcode hashcode与equals方法 集合元素如何判断是否相等 集合如何查看是否包含某个元素
首先记住两句话 相等的两个对象,即equals(Object)方法判断两个对象相等,那么他们必须要有相同的hashcode hashcode相同的两个对象,他们可能相同,也可能不相同 简单地说可以这么 ...
- hashCode及HashMap中的hash()函数
一.hashcode是什么 要理解hashcode首先要理解hash表这个概念 1. 哈希表 hash表也称散列表(Hash table),是根据关键码值(Key value)而直接进行访问的数据结构 ...
- 半夜思考, 为什么建议重写 equals() 方法时, 也要重写 hashCode() 方法
我说的半夜, 并不是真正的半夜, 指的是在我一个人的时候, 我会去思考一些奇怪的问题. 要理解 hashCode() 需要理解下面三个点: hash契约 哈希冲突 哈希可变 第一点: hash 契约指 ...
- java怎么计算散列码hashcode?
转自:https://blog.csdn.net/qq_21430549/article/details/52225801 1.从HashMap说起 我们知道Map以键值对的形式来存储数据.有一点值得 ...
随机推荐
- 火狐开发----如何快速的安装火狐XPI文件
第一步:火狐的自动安装扩展程序,https://addons.mozilla.org/zh-CN/firefox/addon/autoinstaller/ 第二步:安装wget工具,这个Linux应该 ...
- git+webpack项目初始化<一>
目录结构 src + page view image service util git初始化 linux常用命令 rm -rf mmall-fe/ 删除 mkdir mmall-fe 创建文件夹 ls ...
- 单点登录系统和CAS的简介
---恢复内容开始--- 什么是单点登录? 单点登录(Single Sign On),简称为SSO,是目前比较流行的企业业务整合的解决方案之一.SSO的定义是在多个应用系统中,用户只需要登录一次就可以 ...
- EDK II代码实例之Variable
EFI_STATUS Status = EFI_SUCCESS; EFI_GUID OemOSTypeGuid = {0xd06a0bc7, 0x9feb, 0x4cbb, 0xbd, 0x78, 0 ...
- 如何对tcp流认证并加密
一个场景:目前越来越多的业务需要远程读写Redis,而Redis 本身不提供 SSL/TLS 的支持,在需要安全访问的环境下. 这时候就需要额外的手段进行加密认证,这里有两种手段:spiped 和 n ...
- C 语言多线程与锁机制
C 语言多线程与锁机制 多线程 #include <pthread.h> void *TrainModelThread(void *id) { ... pthread_exit(NULL) ...
- markdown test2
#home { width: auto; margin: 0 80px 0 0; } mkdir test. #include <msxml6.h> // 含有 MSXML最新版 #inc ...
- bzoj 1283 序列 - 费用流
题目传送门 传送门 题目大意 给定一个长度为$n$的序列,要求选出一些数使得原序列中每$m$个连续的数中不超过$K$个被选走.问最大的可能的和. 感觉建图好妙啊.. 考虑把问题转化成选$m$次数,每次 ...
- buaacoding_2018算法期末上机G题.地铁建设题解
// 标注:本文旨在为博主确立一种题解的基本范式,以避免博主的题解流于AC代码的粘贴.此基本范式为:完整而简洁明了的思路及其推导说明,力图触及问题的本质并衍生对同类问题的思路分析,使得题解具有泛用性, ...
- python 画广东省等压线图
最近开发时要实现一个业务逻辑: 调用中国气象数据网API接口获取广东省实时气象数据 根据数据,基于广东省地图渲染等压线图 最终效果图是这样的: 首先是获取实时气压数据,由于中国气象数据网每次只能获得3 ...