【09期】说说hashCode() 和 equals() 之间的关系?
程序员的成长之路
共 7415字,需浏览 15分钟
·
2020-08-09 08:49
阅读本文大概需要 6 分钟。
来自:java面试题精选
介绍
equals()
的作用是用来判断两个对象是否相等。hashCode()
的作用是获取哈希码,也称为散列码;它实际上是返回一个int整数。这个哈希码的作用是确定该对象在哈希表中的索引位置。关系
1、不会创建“类对应的散列表”
import java.util.*;
import java.lang.Comparable;
/**
* @desc 比较equals() 返回true 以及 返回false时, hashCode()的值。
*
*/
public class NormalHashCodeTest{
public static void main(String[] args) {
// 新建2个相同内容的Person对象,
// 再用equals比较它们是否相等
Person p1 = new Person("eee", 100);
Person p2 = new Person("eee", 100);
Person p3 = new Person("aaa", 200);
System.out.printf("p1.equals(p2) : %s; p1(%d) p2(%d)\n", p1.equals(p2), p1.hashCode(), p2.hashCode());
System.out.printf("p1.equals(p3) : %s; p1(%d) p3(%d)\n", p1.equals(p3), p1.hashCode(), p3.hashCode());
}
/**
* @desc Person类。
*/
private static class Person {
int age;
String name;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String toString() {
return name + " - " +age;
}
/**
* @desc 覆盖equals方法
*/
public boolean equals(Object obj){
if(obj == null){
return false;
}
//如果是同一个对象返回true,反之返回false
if(this == obj){
return true;
}
//判断是否类型相同
if(this.getClass() != obj.getClass()){
return false;
}
Person person = (Person)obj;
return name.equals(person.name) && age==person.age;
}
}
}
p1.equals(p2) : true; p1(1169863946) p2(1901116749)
p1.equals(p3) : false; p1(1169863946) p3(2131949076)
2、会创建“类对应的散列表”
如果两个对象相等,那么它们的hashCode()值一定相同。这里的相等是指,通过equals()比较两个对象时返回true。
如果两个对象hashCode()相等,它们并不一定相等。因为在散列表中,hashCode()相等,即两个键值对的哈希值相等。然而哈希值相等,并不一定能得出键值对相等。补充说一句:“两个不同的键值对,哈希值相等”,这就是哈希冲突。
import java.util.*;
import java.lang.Comparable;
/**
* @desc 比较equals() 返回true 以及 返回false时, hashCode()的值。
*
*/
public class ConflictHashCodeTest1{
public static void main(String[] args) {
// 新建Person对象,
Person p1 = new Person("eee", 100);
Person p2 = new Person("eee", 100);
Person p3 = new Person("aaa", 200);
// 新建HashSet对象
HashSet set = new HashSet();
set.add(p1);
set.add(p2);
set.add(p3);
// 比较p1 和 p2, 并打印它们的hashCode()
System.out.printf("p1.equals(p2) : %s; p1(%d) p2(%d)\n", p1.equals(p2), p1.hashCode(), p2.hashCode());
// 打印set
System.out.printf("set:%s\n", set);
}
/**
* @desc Person类。
*/
private static class Person {
int age;
String name;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String toString() {
return "("+name + ", " +age+")";
}
/**
* @desc 覆盖equals方法
*/
@Override
public boolean equals(Object obj){
if(obj == null){
return false;
}
//如果是同一个对象返回true,反之返回false
if(this == obj){
return true;
}
//判断是否类型相同
if(this.getClass() != obj.getClass()){
return false;
}
Person person = (Person)obj;
return name.equals(person.name) && age==person.age;
}
}
}
p1.equals(p2) : true; p1(1169863946) p2(1690552137)
set:[(eee, 100), (eee, 100), (aaa, 200)]
import java.util.*;
import java.lang.Comparable;
/**
* @desc 比较equals() 返回true 以及 返回false时, hashCode()的值。
*
*/
public class ConflictHashCodeTest2{
public static void main(String[] args) {
// 新建Person对象,
Person p1 = new Person("eee", 100);
Person p2 = new Person("eee", 100);
Person p3 = new Person("aaa", 200);
Person p4 = new Person("EEE", 100);
// 新建HashSet对象
HashSet set = new HashSet();
set.add(p1);
set.add(p2);
set.add(p3);
// 比较p1 和 p2, 并打印它们的hashCode()
System.out.printf("p1.equals(p2) : %s; p1(%d) p2(%d)\n", p1.equals(p2), p1.hashCode(), p2.hashCode());
// 比较p1 和 p4, 并打印它们的hashCode()
System.out.printf("p1.equals(p4) : %s; p1(%d) p4(%d)\n", p1.equals(p4), p1.hashCode(), p4.hashCode());
// 打印set
System.out.printf("set:%s\n", set);
}
/**
* @desc Person类。
*/
private static class Person {
int age;
String name;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String toString() {
return name + " - " +age;
}
/**
* @desc重写hashCode
*/
@Override
public int hashCode(){
int nameHash = name.toUpperCase().hashCode();
return nameHash ^ age;
}
/**
* @desc 覆盖equals方法
*/
@Override
public boolean equals(Object obj){
if(obj == null){
return false;
}
//如果是同一个对象返回true,反之返回false
if(this == obj){
return true;
}
//判断是否类型相同
if(this.getClass() != obj.getClass()){
return false;
}
Person person = (Person)obj;
return name.equals(person.name) && age==person.age;
}
}
}
p1.equals(p2) : true; p1(68545) p2(68545)
p1.equals(p4) : false; p1(68545) p4(68545)
set:[aaa - 200, eee - 100]
原则
如果一个key对象在put的时候调用hashCode()决定了存放的位置,而在get的时候调用hashCode()得到了不一样的返回值,这个值映射到了一个和原来不一样的地方,那么肯定就找不到原来那个键值对了。
推荐阅读:
毕设有着落了!一套开源的,基于SpringBoot的车牌识别系统
微信扫描二维码,关注我的公众号
朕已阅
评论