深入理解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以键值对的形式来存储数据.有一点值得 ...
随机推荐
- java项目word文件转html文件
最近在项目开发中用户提出要在电脑上没有装office时在浏览器中打开word文件,最后确定的逻辑:用户选择想要查看的文件,页面js判断文件是否为word.不是执行下载,是后端根据word文件后缀访问对 ...
- Vue-Router路由Vue-CLI脚手架和模块化开发 之 vue-router路由
vue-router路由:Vue.js官网推出的路由管理器,方便的构建单页应用: 单页应用(SPA)只有一个web页面的应用,用户与应用交互时,动态更新该页面的内容:简单来说,根据不同的url与数据, ...
- 隐藏软键盘(解决自定义Dialog中无法隐藏的问题)
/** * Dialog中隐藏软键盘不管用 * @param activity */ public static void HideSoftKeyBoard(Activity activity){ t ...
- 国际空间站直播 ISS直播
b站:https://live.bilibili.com/9196015 斗鱼:https://www.douyu.com/543816 欢迎大家 (ฅ´ω`ฅ)
- vue 父组件调用子组件内置方法
背景介绍:外派到泰康做项目.这个项目中有个选择组织的功能,是一个树桩结构的懒加载,于是我就element-ui的tree组件封装了一个公共的组件. 但是后来发现他们的公司组织结构不是都请求的同一个接口 ...
- Java 诊断工具 Arthas 教程学习笔记
Java 诊断利器 Arthas,是阿里的一款开源工具.Github-alibaba/arthas 上可以看到它的介绍.了解它,主要是最近对分析 Java 错误堆栈比较感兴趣,机缘巧合看到了它. 本文 ...
- 【做题】ECFinal2018 J - Philosophical … Balance——dp
原文链接 https://www.cnblogs.com/cly-none/p/ECFINAL2018J.html 题意:给出一个长度为\(n\)的字符串\(s\),要求给\(s\)的每个后缀\(s[ ...
- MySQL之 视图,触发器,存储过程,函数,事物,数据库锁,数据库备份
1.视图 视图: 是一个虚拟表,其内容由查询定义: 视图有如下特点; 1. 视图的列可以来自不同的表,是表的抽象和逻辑意义上建立的新关系. 2. 视图是由基本表(实表)产生的表(虚表). 3. ...
- 殊途同归 - Church-Rosser and Consistency of Evaluation
在"解释语言的语言"中提到,设计一个新的语言,仅仅是使用meta-language给出其描述是不够的,我们还需要去验证一些性质. 考虑一下我们在"解释语言 ...
- 2018年底,IOS面试题的复习之OC的反射机制
明天要去面试一个公司,今天复习下IOS题目吧 1.说一下OC的反射机制 答:OC的反射机制类似于JAVA的反射机制,这种动态反射机制可以让OC语言更加灵活.这句话是对反射机制的初步认识,具体表现在哪里 ...