[复习]java中hashCode的作用
1.HashCode的官方文档定义
(1)hashcode方法返回该对象的哈希码值。支持该方法是为哈希表提供一些优点,例如java.util.HashTable提供的哈希表。
(2)hashCode的常规协定是:在java应用程序执行期间,在同一对象上多次调用hashcode的方法的时候,必须一致的放回相同的值,前提是对象上equals比较中所用的信息没有被修改,从某应用程序的一次执行到同一程序的另一次执行,该值无需保持一致。
(3)如果根据equals()方法,两个对象是相等的,那么在两个对象中的每个对象调用hashcode方法都必须生成相同的值。
如果根据 equals(java.lang.Object) 方法得到两个对象不相等,那么在两个对象中的任一对象上调用 hashCode 方法必定会生成不同的整数结果。但是,程序员应该知道,为不相等的对象生成不同整数结果可以提高哈希表的性能。实际上,由 Object 类定义的 hashCode 方法确实会针对不同的对象返回不同的整数。(这一般是通过将该对象的内部地址转换成一个整数来实现的。当equals方法被重写时,通常有必要重写 hashCode 方法,以维护 hashCode 方法的常规协定,该协定声明相等对象必须具有相等的哈希码。
2.对上述文档进行总结
(1)hashCode的存在主要是用于查找的快捷性,如Hashtable,HashMap等,hashCode是用来在散列存储结构中确定对象的存储地址的
(2)如果两个对象相同,就是适用于equals(Java.lang.Object) 方法,那么这两个对象的hashCode一定要相同
(3)如果对象的equals方法被重写,那么对象的hashCode也尽量重写,并且产生hashCode使用的对象,一定要和equals方法中使用的一致
(4)两个对象的hashCode相同,并不一定表示两个对象就相同,也就是不一定适用于equals(java.lang.Object) 方法,只能够说明这两个对象在散列存储结构中,如Hashtable,他们“存放在同一个篮子里”。
3.再来说下hashCode和equals之间有什么关系吧?
(1)已知:hashcode是用来查找的,比如 内存中有这么几个位置0 1 2 3 4 5 6 7 8 9,我们定义了包含id属性字段的一个类,我要把类存放在以上10个位置中的一个,如果不用hashcode而任意存放,那么查找只能遍历或者二分之类的查找,这时候我们的hashcode闪亮登场。
用一种比较简单的hash编码方法,如id字段%10取余得到的是hashcode,然后把类放在hashcode的那个位置,如id=9,9%10=9,这样类就放在9的那个位置,这样在查找的时候可以通过id%10来直接找到类存放的位置了。
(2)两个类有相同的hashcode怎么办,如9和19得到的hashcode相同,当然我们这里不是要说hash冲突啊,会有专门的一篇将hashcode算法和冲突的,那我们该如何找到我们要找的那个类,这就是equals了,我们先用hashcode找到类放在哪里,再通过equals找到我们要找的类,所以重写equals()也要重写hashcode,因为不通过hashcode先找到那个类放在哪,光重写equals也没有意义啊
自己举例说明下,看完你就相信这两兄弟确实关系密切啊?
test-1
public class testPlay {
private int i;
public int getI() {
return i;
}
public void setI(int i) {
this.i = i;
}
public int hashCode() {
return i % 10;
}
public final static void main(String[] args) {
testPlay a = new testPlay();
testPlay b = new testPlay();
a.setI(1);
b.setI(1);
Set<testPlay> set = new HashSet<>();
set.add(a);
set.add(b);
System.out.println(a.hashCode() == b.hashCode());
System.out.println(a.equals(b));
System.out.println(set);
}
以上输出:
true
false
[com.xrxs.waves.testPlay@1, com.xrxs.waves.testPlay@1]
可以看书,重写了hashcode方法之后,两个对象的hashcode相等,但是两个对象不相同,那是因为我们没有重写equals方法。这样就会调用类中默认的equals方法,会比较两个对象的引用是不是相同,自然是不相同了,对于hashset来说,只能放唯一的对象,也就是相同的对象只能存放一个,所以这里我们发现确实两个对象都被放进去了。所以我们再来一次加上equals方法,看否相同。
test-2
public class testPlay2 {
private int i;
public int getI() {
return i;
}
public void setI(int i) {
this.i = i;
}
public boolean equals(Object object) {
if (object == null) {
return false;
}
if (object == this) {
return true;
}
if (!(object instanceof testPlay2)) {
return false;
}
testPlay2 other = (testPlay2) object;
if (other.getI() == this.getI()) {
return true;
}
return false;
}
public int hashCode() {
return i % 10;
}
public final static void main(String[] args) {
testPlay2 a = new testPlay2();
testPlay2 b = new testPlay2();
a.setI(1);
b.setI(1);
Set<testPlay2> set = new HashSet<>();
set.add(a);
set.add(b);
System.out.println(a.hashCode() == b.hashCode());
System.out.println(a.equals(b));
System.out.println(set);
}
}
以上输出:
true
true
[com.xrxs.waves.testPlay2@1]
我们发现两个对象相同了,hashset中也只有一个对象。所以重写hashcode请不要忘了重写equals哦
[复习]java中hashCode的作用的更多相关文章
- Java中hashCode的作用
转 http://blog.csdn.net/fenglibing/article/details/8905007 Java中hashCode的作用 2013-05-09 13:54 64351人阅 ...
- 【转】Java中hashCode的作用
以下是关于HashCode的官方文档定义: hashcode方法返回该对象的哈希码值.支持该方法是为哈希表提供一些优点,例如,java.util.Hashtable 提供的哈希表. hashCode ...
- java 中hashcode和equals 总结
一.概述 在Java中hashCode的实现总是伴随着equals,他们是紧密配合的,你要是自己设计了其中一个,就要设计另外一个.当然在多数情况下,这两个方法是不用我们考虑的,直 ...
- 深刻理解Java中final的作用(一):从final的作用剖析String被设计成不可变类的深层原因
声明:本博客为原创博客,未经同意,不得转载!小伙伴们假设是在别的地方看到的话,建议还是来csdn上看吧(原文链接为http://blog.csdn.net/bettarwang/article/det ...
- Java中hashcode的理解
Java中hashcode的理解 原文链接http://blog.csdn.net/chinayuan/article/details/3345559 怎样理解hashCode的作用: 以 java. ...
- JAVA中protected的作用
JAVA中protected的作用 1.public:public表明该数据成员.成员函数是对所有用户开放的,所有用户都可以直接进行调用 2.private:private表示私有,私有的意思就是 ...
- Java中Volatile的作用
Java中Volatile的作用 看了几篇博客,发现没搞懂.可是简单来说,就是在我们的多线程开发中.我们用Volatile关键字来限定某个变量或者属性时,线程在每次使用变量的时候.都会读取变量改动后的 ...
- Java中HashCode()和equals()的作用
引言 我们知道Java中的集合(Collection)大致可以分为两类,一类是List,再有一类是Set. 前者集合内的元素是有序的,元素可以重复:后者元素无序,但元素不可重复. 这里就引出一个问题: ...
- Java中hashCode()方法以及HashMap()中hash()方法
Java的Object类中有一个hashCode()方法: public final native Class<?> getClass(); public native int hashC ...
随机推荐
- SQL递归查询知多少
最近工作中遇到了一个问题,需要根据保存的流程数据,构建流程图.数据库中保持的流程数据是树形结构的,表结构及数据如下图: 仔细观察表结构,会发现其树形结构的特点: FFIRSTNODE:标记是否为根节点 ...
- java_监控工具jvisualvm
转:使用 VisualVM 进行性能分析及调优 启动:jvisualvm 首先到JDK安装目录/bin目录下,双击jvisualvm.exe文件启动 需要注意的是:当OS所在分区是FAT格式时,Vis ...
- JavaScript易混淆知识点小回顾--数组方法与字符串方法;
数组属性: arr.length;查看数组的长度 arr.Pop;删除数组最后一个元素; 数组的方法: arr.push();添加到数组末端; arr.shift();删除数组的第一个元素; arr. ...
- java学习阶段三:运算符和结构学习
import java.util.Scanner;/* * JAVA中运算符的学习: * 算术运算符:+.-.*./ 和 %,两个整数相除,结果还是整数. * 赋值运算符:=.+=.-=.*=./=. ...
- 网站SEO,HTTP请求的关键数字----6
客户端浏览器向服务器请求一个网页素材. 那么网页素材是通过什么方式,什么顺序被下载下来的呢. 我今天做了个简单的测试. 首先,准备测试文件 写一个网页,网页中引用若干的资源文件. 同一文件的不同的参数 ...
- ReactNative入门(2)ECMAScript 6简介
ECMAScript 6(以下简称ES6)是JavaScript语言的下一代标准.因为当前版本的ES6是在2015年发布的,所以又称ECMAScript 2015. 也就是说,ES6就是ES2015. ...
- VMware WorkStation9.0虚拟机如何运行WINPE
VMware WorkStation9.0虚拟机如何运行WINPE...我们在使用VMware的过程中,有些时候需要让VMware来运行WINPE系统,比如在使用VMware进行系统封装的过程中,其中 ...
- rips中如何使用PHP虚拟机自带函数--token_get_all
这两天在看rips源码,发现,它在审计php代码时调用了php虚拟机自带的token_get_all此函数. 这一函数会将php源码按照内置的规则进行归纳,并输出成数组格式. 如: <?php ...
- XML与JavaScript知识
什么是XMLHttpRequest 对象? 答:XMLHttpRequest 对象用于在后台与服务器交换数据,它是开发者的梦想,因为它能够:1.在不重新加载页面的情况下更新网页:2.在页面已加载后从服 ...
- 不要怂,就是GAN (生成式对抗网络) (六):Wasserstein GAN(WGAN) TensorFlow 代码
先来梳理一下我们之前所写的代码,原始的生成对抗网络,所要优化的目标函数为: 此目标函数可以分为两部分来看: ①固定生成器 G,优化判别器 D, 则上式可以写成如下形式: 可以转化为最小化形式: 我们编 ...