
Hashcode和equals的知识点。
Hashcode
Hashcode的作用
获取哈希码(为int数据类型)。
哈希码(散列码)的作用
确定该对象在哈希表中的位置。
哈希表的作用
在栈中(利用哈希码)快速找到对象的位置。
以key-value
对储存。
哈希冲突
由于哈希算法被计算的数据是无限的,而计算后的结果范围有限,因此总会存在不同的数据经过计算后得到的值相同,这就是哈希冲突。(两个不同的数据计算后的结果一样)
hashset的录入过程

简易流程图

使用Hashcode的意义
在比较equals之前,先比较hashcode可以大大减少使用equals的次数,提高执行的性能。
equals
所有类继承object
类中的equals()方法,**默认使用的是==**。
==和equals
==为对比栈中的数据。
- 基本类型数据:比对变量值
- 引用类型数据: 比对对象的地址
| String s1 = "abc"; String s2 = "abc"; System.out.println("s1的hashcode:" + s1.hashCode()); System.out.println("s2的hashcode:" + s2.hashCode()); System.out.print("s1 == s2:" ); System.out.println( s1 == s2); System.out.println("s1.equals(s2):" + s1.equals(s2));
|
结果:
| s1的hashcode:96354 s2的hashcode:96354 s1 == s2:true s1.equals(s2):true
|
String重写equals
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| public boolean equals(Object anObject) { if (this == anObject) { return true; } if (anObject instanceof String) { String anotherString = (String)anObject; int n = value.length; if (n == anotherString.value.length) { char v1[] = value; char v2[] = anotherString.value; int i = 0; while (n-- != 0) { if (v1[i] != v2[i]) return false; i++; } return true; } } return false; }
|
对每个char进行对比。
为什么重写equals()必须重写hashcode()
hashcode的使用原则
- 对象相等,hashcode必须相等
- hashcode相等,对象不一定相等
- 两对象相等,则equals相等
- hashcode()的默认行为是对堆上的对象产生独特值。如果没有重写hashcode,则同一class的两个对象无论如何也不会相等。
代码验证
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| package com.ajie.controller;
import java.util.HashMap;
public class Test { public static void main(String[] args) { Student s1 = new Student("Tom", 12); Student s2 = new Student("Tom", 12); System.out.println("s1 equals s2 ?"+s1.equals(s2)); System.out.println("s1 hashCode:"+s1.hashCode()); System.out.println("s2 hashCode:"+s2.hashCode()); HashMap<Student, Integer> hashMap = new HashMap<Student, Integer>(); hashMap.put(s1, 1); System.out.println(hashMap.get(s2)); } } class Student { private String name; private int age;
public Student(String name, int age) { this.name = name; this.age = age; }
@Override public boolean equals(Object o) { if(this == o) { return true; } if(o == null || getClass() != o.getClass()) { return false; } Student s = (Student) o; return age == s.age && name.equals(s.name); }
}
|
运行结果
| s1 equals s2 ?true s1 hashCode:366712642 s2 hashCode:1829164700 null
|
我们Student类重写了equals方法,hashCode方法没有重写.
s1和s2是同一class生成的两个属性相同的对象,equals方法为true,认为是同一个人。但是s1和s2的hashCode返回不同。
参考
Java重写equals方法时为什么要重写hashCode方法_掘客DIGGKR-CSDN博客
限时分享!阿里P8熬了2个月肝出500道Java面试必考题(最全面系统的Java核心知识点)_哔哩哔哩_bilibili