HashCode方法
- HashCode方法是属于Object父类提供的方法,HashCode方法返回该对象的哈希码值。支持该方法是为哈希表提供一些优点,例如,java.util.Hashtable提供的哈希表
- HashCode的常规协定是:在Java应用程序执行期间,在同一个对象上多次调用hashCode方法时,必须一致地返回相同的整数。
- HashCode的存在主要是用于查找的快捷性,如Hashtable,HashMap等,HashCode是用来在散列存储结构中确定对象的存储地址的
- 如果equals方法比较相等,则HashCode值也一定相等,但是HashCode值相等不代表equals比较也相等
- 如果类中重写了 equals 方法 必须要重写 HashCode 方法
【强制】关于 hashCode 和 equals的处理,遵循如下规则:
- 只要重写 equals,就必须重写 hashCode
- 因为Set 存储的是不重复的对象,依据 hashCode和equals 进行判断,所以 Set存储的对象必须重写这两个方法
- 如果自定义对象作为 Map 的键,那么必须覆写 hashCode 和equals
说明:String 因为重写了hashCode 和 equals 方法,所以我们可以愉快地使用 String 对象作为 Key 来使用
示例代码
package com.collection.Demo10;
import java.util.Objects;
public class MayktEntity {
private String name;
private Integer age;
public MayktEntity(String name, Integer age) {
this.name = name;
this.age = age;
}
@Override
public boolean equals(Object o) {
//先判断两个对象内存地址是否相同
if (this == o) return true;
//如果第二的对象为null或者 两个类型不相等 返回false
if (o == null || getClass() != o.getClass()) return false;
//比较两个对象的成员属性值是否相等
MayktEntity that = (MayktEntity) o;
// return (this.name.equals(that.name)) && (this.age.equals(that.age));//等价与下一行
return Objects.equals(name, that.name) && Objects.equals(age, that.age);
}
/**
* public static boolean equals(Object a, Object b) {
* return (a == b) || (a != null && a.equals(b));
* }
* <p>
* public boolean equals(Object obj) {
* return (this == obj);
* }
*/
@Override
public int hashCode() {
return Objects.hash(name, age);
// return this.name.hashCode() + this.age.hashCode();//这行是将两个hash值相加,可以看到两个对象的hash是否相等,
//但与上面一行不等价
}
}
package com.collection.Demo10;
public class Test02 {
public static void main(String[] args) {
/**
* equals作用:equals就是在比较两个对象的值是否相等(误区)
* equals属于Object父类中 默认的情况下 在比较两个对象的内存地址是否相同
* 如果想要能够实现比较两个对象中成员属性值是否相等 需要重写父类中的equals()
*/
String str1 = "mayikt";
String str2 = "mayikt";
System.out.println(str1 == str2);//true
System.out.println(str1.equals(str2));//true 问题:这里的equals为什么是为true?
//∵ String类中 重写父类中的equals() 比较两个字符串值是否相同
MayktEntity maykt1 = new MayktEntity("mayikt", 22);
MayktEntity maykt2 = new MayktEntity("mayikt", 22);
System.out.println(maykt1.equals(maykt2));//false 这里实际上 等价与mayikt1==mayikt2 比较两个对象的内存地址是否相同
//如果上面在MayiktEntity中重写了equals(),maykt1.equals(maykt2) 结果为 true
System.out.println(maykt1 == maykt2);//false
//如果只重写equals,不重写hashCode() 两个值是不一样的
System.out.println(maykt1.hashCode());//1163157884 重写后:845662570
System.out.println(maykt2.hashCode());//1956725890 重写后:845662570
}
}
package com.collection.Demo10;
public class Test03 {
public static void main(String[] args) {
/**
* HashCode?
* hashCode 属于 object父类中 Java虚拟机提供 给每个对象生成一个 hashCode值 整数类型(int)
* hashCode值生成规则:堆内存地址转化成整数类型
*/
String str1 = "mayikt1";
String str2 = "mayikt2";
String str3 = "mayikt2";
System.out.println(str1.equals(str2));//false
System.out.println(str1.hashCode());//845661636
System.out.println(str2.hashCode());//845661637
System.out.println(str3.hashCode());//845661637
Object o = new Object();
System.out.println(o.hashCode());//1163157884
/**
* 1.如果使用equals方法比较两个对象相等,则HashCode值一定相等
* 2.但是两个对象的HashCode值相等 不代表使用equals比较也相等
* 3.如果两个对象的HashCode值相等,但是值是不同的 专业术语:Hash冲突问题
* HashMap集合底层源码 根据该对象的HashCode值计算存放到数组中index位置
*/
String strA = "a";
Integer int97 = 97;//这里只可以用Integer 引用类型,int类型 不可以使用hashCode
//整数类型 包装类Integer hashCode值是多少呢?——就是该整数类型值 97
System.out.println(strA.hashCode());//97
System.out.println(int97.hashCode());//97
System.out.println(strA.equals(int97));//false
}
/**
* MD5 加密底层算法——hash算法
* 相同的内容 做MD5 得到md5值是一样的
*/
}
下一篇文章:HashMap常见的面试题