hashCode()–equals()
hashCode() 返回哈希值
hash和hash表是什么
hash是一个函数,该函数中的实现就是一种算法,就是通过一系列的算法来得到一个hash值。这个时候,我们就需要知道另一个东西,hash表,通过hash算法得到的hash值就在这张hash表中,也就是说,hash表就是所有的hash值组成的,有很多种hash函数,也就代表着有很多种算法得到hash值,如上面截图的三种,等会我们就拿第一种来说。
hashcode是什么?
hashcode
hashcode代表对象的地址说的是对象在hash表中的位置
HashCode的存在主要是为了查找的快捷性,HashCode是用来在散列存储结构中确定对象的存储地址的(后半句说的用hashcode来代表对象就是在hash表中的位置
hashCode()
理理想的哈希函数应当具有均匀性,即不不相等的对象应当均匀分布到所有可能的哈希值上。这就要求了了哈 希函数要把所有域的值都考虑进来。可以将每个域都当成 R 进制的某⼀一位,然后组成⼀一个 R 进制的整 数。
R ⼀一般取 31,因为它是⼀一个奇素数,如果是偶数的话,当出现乘法溢出,信息就会丢失,因为与 2 相 乘相当于向左移⼀一位,最左边的位丢失。并且⼀一个数与 31 相乘可以转换成移位和减法: 31*x == (x<<5)-x ,编译器器会⾃自动进⾏行行这个优化。
@Override
public int hashCode() {
int result = 17;
result = 31 * result + x;
result = 31 * result + y;
result = 31 * result + z;
return result;}
测试实例
目的
检查是否为同⼀一个对象的引⽤用,如果是直接返回 true; 检查是否是同⼀一个类型,如果不不是,直接返回 false; 将 Object 对象进⾏行行转型;
判断每个关键域是否相等。
新建了了两个等价的对象,并将它们添加到 HashSet 中。我们希望将这两个对象当成⼀一样 的,只在集合中添加⼀一个对象。但是 EqualExample 没有实现 hashCode() ⽅方法,因此这两个对象的哈 希值是不不同的,最终导致集合添加了了两个等价的对象。
不重写
package com.shiyi.hashCodeDemo;
public class EqualExample {
private int x;
private int y;
private int z;
public EqualExample(int x, int y, int z) {
this.x = x;
this.y = y;
this.z = z; }
//@Override
//public boolean equals(Object o) {
// if (this == o) return true;
// if (o == null || getClass() != o.getClass()) return false;
// EqualExample that = (EqualExample) o;
// if (x != that.x) return false;
// if (y != that.y) return false;
// return z == that.z;
//}
// @Override
// public int hashCode() {
// int result = 17;
// result = 31 * result + x;
// result = 31 * result + y;
// result = 31 * result + z;
// return result;
// }
}
package com.shiyi.hashCodeDemo;
import java.util.HashSet;
public class test {
public static void main(String[] args) {
EqualExample e1 = new EqualExample(1, 1, 1);
EqualExample e2 = new EqualExample(1, 1, 1);
System.out.println(e1.equals(e2)); // true
HashSet<EqualExample> set = new HashSet<>();
set.add(e1);
set.add(e2);
System.out.println(e1.hashCode());//e1hashcode
System.out.println(e2.hashCode());//e2hashcode
EqualExample equalExample=e1;
System.out.println(equalExample.hashCode());//equalExample hashcode
EqualExample equalExample2=(EqualExample) e1;
System.out.println(equalExample2.hashCode());//equalExample2 hashcode
System.out.println(equalExample.hashCode()==equalExample2.hashCode());//hashcode ==同类不同实例
System.out.println(equalExample.hashCode()==e2.hashCode());//不同类不同实例
System.out.println(equalExample.equals(e2));//equal同一类
System.out.println(set.size()); // 2
System.out.println(e1.toString());//tostring
//false
//692404036
//1554874502
//692404036
//692404036
//true
//false
//false
//2
//com.shiyi.hashCodeDemo.EqualExample@29453f44
}
}
只重写equals
package com.shiyi.hashCodeDemo;
public class EqualExample {
private int x;
private int y;
private int z;
public EqualExample(int x, int y, int z) {
this.x = x;
this.y = y;
this.z = z; }
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
EqualExample that = (EqualExample) o;
if (x != that.x) return false;
if (y != that.y) return false;
return z == that.z;
} }
package com.shiyi.hashCodeDemo;
import java.util.HashSet;
public class test {
public static void main(String[] args) {
EqualExample e1 = new EqualExample(1, 1, 1);
EqualExample e2 = new EqualExample(1, 1, 1);
System.out.println(e1.equals(e2)); // true
HashSet<EqualExample> set = new HashSet<>();
set.add(e1);
set.add(e2);
System.out.println(e1.hashCode());//e1hashcode
System.out.println(e2.hashCode());//e2hashcode
EqualExample equalExample=e1;
System.out.println(equalExample.hashCode());//equalExample hashcode
EqualExample equalExample2=(EqualExample) e1;
System.out.println(equalExample2.hashCode());//equalExample2 hashcode
System.out.println(equalExample.hashCode()==equalExample2.hashCode());//hashcode ==同类不同实例
System.out.println(equalExample.hashCode()==e2.hashCode());//不同类不同实例
System.out.println(equalExample.equals(e2));//equal同一类
System.out.println(set.size()); // 2
System.out.println(e1.toString());//tostring
// true
//692404036
//1554874502
//692404036
//692404036
//true
//false
//true
//2
//com.shiyi.hashCodeDemo.EqualExample@29453f44
}
}
重写equals与hashcode
package com.shiyi.hashCodeDemo;
public class EqualExample {
private int x;
private int y;
private int z;
public EqualExample(int x, int y, int z) {
this.x = x;
this.y = y;
this.z = z; }
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
EqualExample that = (EqualExample) o;
if (x != that.x) return false;
if (y != that.y) return false;
return z == that.z;
}
@Override
public int hashCode() {
int result = 17;
result = 31 * result + x;
result = 31 * result + y;
result = 31 * result + z;
return result;
}
}
package com.shiyi.hashCodeDemo;
import java.util.HashSet;
public class test {
public static void main(String[] args) {
EqualExample e1 = new EqualExample(1, 1, 1);
EqualExample e2 = new EqualExample(1, 1, 1);
System.out.println(e1.equals(e2)); // true
HashSet<EqualExample> set = new HashSet<>();
set.add(e1);
set.add(e2);
System.out.println(e1.hashCode());//e1hashcode
System.out.println(e2.hashCode());//e2hashcode
EqualExample equalExample=e1;
System.out.println(equalExample.hashCode());//equalExample hashcode
EqualExample equalExample2=(EqualExample) e1;
System.out.println(equalExample2.hashCode());//equalExample2 hashcode
System.out.println(equalExample.hashCode()==equalExample2.hashCode());//hashcode ==同类不同实例
System.out.println(equalExample.hashCode()==e2.hashCode());//不同类不同实例
System.out.println(equalExample.equals(e2));//equal同一类
System.out.println(set.size()); // 2
System.out.println(e1.toString());//tostring
//true
//507440
//507440
//507440
//507440
//true
//true
//true
//1
// com.shiyi.hashCodeDemo.EqualExample@7be30
}
}
运行结果改变
集合中添加了唯一一个对象
原来 | //e1.equals(e2) //e1hashcode //e2hashcode //equalExample hashcode //equalExample2 hashcode //hashcode ==同类不同实例 //不同类不同实例 //equal同一类 // 2 //tostring |
---|---|
重写equals | // true //692404036 //1554874502 //692404036 //692404036 //true //false //true //2 //com.shiyi.hashCodeDemo.EqualExample@29453f44 |
重写equals与hashcode | //true //507440 //507440 //507440 //507440 //true //true //true //1 // com.shiyi.hashCodeDemo.EqualExample@7be30 |
都不重写 | //false //692404036 //1554874502 //692404036 //692404036 //true //false //false //2 //com.shiyi.hashCodeDemo.EqualExample@29453f44 |