说说 hashcode() 和 equals() 的作用、区别、联系?
1、equal()相等的两个对象他们的hashCode()肯定相等,也就是用equal()对比是绝对可靠的。
2、hashCode()相等的两个对象他们的equal()不一定相等,也就是hashCode()不是绝对可靠的。
int num;
String name;
public int hashCode(){
return num*name.hashCode();
}
}
哈希码(HashCode)
哈希码产生的依据:哈希码并不是完全唯一的,它是一种算法,让同一个类的对象按照自己不同的特征尽量的有不同的哈希码,但不表示不同的对象哈希码完全不同。也有相同的情况,看程序员如何写哈希码的算法。
什么是哈希码(HashCode)
String str1 = "aa", str1.hashCode= 3104
String str2 = "bb", str2.hashCode= 3106
String str3 = "aa", str3.hashCode= 3104
根据HashCode由此可得出str1!=str2,str1==str3
3、Integer类,返回的哈希码就是Integer对象里所包含的那个整数的数值,例如Integer i1=new Integer(100),i1.hashCode的值就是100 。由此可见,2个一样大小的Integer对象,返回的哈希码也一样。
equals方法在hibernate中的应用
User u1 = new User("张三");
User u2 = new User("李四");
User u3 = new User("张三");
public class User{
private String userName;
….//get ,set方法省
//覆盖Object里的equals方法
public boolean equals(Object arg0){
if (!(arg0 instanceof User)){
return false;
}
User user = (User)arg0;
//如果名字相同,则表示属于同一个对象。
if(user.getName().equals(this.getName)){
return true;
}else{
return false;
}
}
这样hibernate在插入数据的时候,如果传过来一个叫”张三”的用户,hibernate会先判断有没有叫“张三”的用户,如果没有,就允许插入,如果有,就不允许插入。这样做可以保证数据的高度一致性,不同的项目有不同的需求,所以要根据自己的需求来覆盖equals方法。
equals和HashCode的关系
User u1 = new User("张三");
User u2 = new User("张三");
由于我们重写了User的equals方法,所以 u1.equals(u2);返回true 但是,User并没有重写hashCode方法,它用的是Object类的hashCode方法,所以 u1.hashCode = 31050006 u2.hashCode = 31587890 两者的hashCode并不相等。违背了hibernate的原则 由此hibernate会产生错误判断,又以为它们不是同一个对象,因此我们还得重写User 的hashCode方法。如何重写hashCode方法呢?
HashCode的重写
public class User{
private String userName;
//覆盖Object里的equals方法
public boolean equals(Object arg0){
if(!(arg0 instanceof User)){
return false;
}
User user = (User)arg0;
//如果名字相同,则表示属于同一个对象。
if (user.getName().equals(this.getName)){
return true;
}else{
return false;
}
}
//覆盖Object里的hashCode方法
public int hashCode() {
return name.hashCode();//返回名字的哈希码。
}
}
hashcode()和equals()关系
//学生类
public class Student {
private int age;
private String name;
public Student() {
}
public Student(int age, String name) {
super();
this.age = age;
this.name = name;
}
public int getAge() {
return age;
}
public String getName() {
return name;
}
public void setAge(int age) {
this.age = age;
}
public void setName(String name) {
this.name = name;
}
}
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Set;
public class EqualsTest {
public static void main(String[] args) {
LinkedList<Student> list = new LinkedList<Student>();
Set<Student> set = new HashSet<Student>();
Student stu1 = new Student(3,"张三");
Student stu2 = new Student(3,"张三");
System.out.println("stu1 == stu2 : "+(stu1 == stu2));
System.out.println("stu1.equals(stu2) : "+stu1.equals(stu2));
list.add(stu1);
list.add(stu2);
System.out.println("list size:"+ list.size());
set.add(stu1);
set.add(stu2);
System.out.println("set size:"+ set.size());
}
}
stu1 == stu2 : false
stu1.equals(stu2) : false
list size:2
set size:2
//学生类
public class Student {
private int age;
private String name;
public Student() {
}
public Student(int age, String name) {
super();
this.age = age;
this.name = name;
}
public int getAge() {
return age;
}
public String getName() {
return name;
}
public void setAge(int age) {
this.age = age;
}
public void setName(String name) {
this.name = name;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Student other = (Student) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
}
stu1 == stu2 : false
stu1.equals(stu2) : true
list size:2
set size:2
结果分析:因为Student两个对象的age和name属性相等,而且又是通过覆盖equals方法来判断的,所示stu1.equals(stu2) 为true。注意以上几次测试list和set的size都是2
//学生类
public class Student {
private int age;
private String name;
public Student() {
}
public Student(int age, String name) {
super();
this.age = age;
this.name = name;
}
public int getAge() {
return age;
}
public String getName() {
return name;
}
public void setAge(int age) {
this.age = age;
}
public void setName(String name) {
this.name = name;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
}
stu1 == stu2 : false
stu1.equals(stu2) : false
list size:2
hashCode :775943
hashCode :775943
set size:2
//学生类
public class Student {
private int age;
private String name;
public Student() {
}
public Student(int age, String name) {
super();
this.age = age;
this.name = name;
}
public int getAge() {
return age;
}
public String getName() {
return name;
}
public void setAge(int age) {
this.age = age;
}
public void setName(String name) {
this.name = name;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
System.out.println("hashCode : "+ result);
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Student other = (Student) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
}
stu1 == stu2 : false
stu1.equals(stu2) :true
list size:2
hashCode :775943
hashCode :775943
set size:1
//学生类
public class Student {
private int age;
private String name;
<span style="color:#ff0000;">private static int index=5;</span>
public Student() {
}
public Student(int age, String name) {
super();
this.age = age;
this.name = name;
}
public int getAge() {
return age;
}
public String getName() {
return name;
}
public void setAge(int age) {
this.age = age;
}
public void setName(String name) {
this.name = name;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + <span style="color:#ff0000;">(age+index++)</span>;
result = prime * result + ((name == null) ? 0 : name.hashCode());
<span style="color:#ff0000;">System.out.println("result :"+result);</span>
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Student other = (Student) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
}
stu1 == stu2 : false
stu1.equals(stu2) : true
list size:2
hashCode :776098
hashCode :776129
set size:2
//学生类
public class Student {
private int age;
private String name;
public Student() {
}
public Student(int age, String name) {
super();
this.age = age;
this.name = name;
}
public int getAge() {
return age;
}
public String getName() {
return name;
}
public void setAge(int age) {
this.age = age;
}
public void setName(String name) {
this.name = name;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
System.out.println("hashCode : "+ result);
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Student other = (Student) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
}
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Set;
public class EqualsTest {
public static void main(String[] args) {
LinkedList<Student> list = new LinkedList<Student>();
Set<Student> set = new HashSet<Student>();
Student stu1 = new Student(3,"张三");
Student stu2 = new Student(3,"张三");
System.out.println("stu1 == stu2 : "+(stu1 == stu2));
System.out.println("stu1.equals(stu2) : "+stu1.equals(stu2));
list.add(stu1);
list.add(stu2);
System.out.println("list size:"+ list.size());
set.add(stu1);
set.add(stu2);
System.out.println("set size:"+ set.size());
stu1.setAge(34);
System.out.println("remove stu1 : "+set.remove(stu1));
System.out.println("set size:"+ set.size());
}
}
stu1 == stu2 : false
stu1.equals(stu2) : true
list size:2
hashCode : 775943
hashCode : 775943
set size:1
hashCode : 776904
remove stu1 : false
set size:1
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
public V put(K key, V value) {
if (key == null)
return putForNullKey(value);
int hash = hash(key.hashCode());
int i = indexFor(hash, table.length);
for (Entry<K,V> e = table[i]; e != null; e = e.next) {
Object k;
if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
V oldValue = e.value;
e.value = value;
e.recordAccess(this);
return oldValue;
}
}
modCount++;
addEntry(hash, key, value, i);
return null;
}
作者:路修远而求索
www.cnblogs.com/keyi/p/7119825.html
公众号“大咖笔记”所发表内容注明来源的,版权归原出处所有(无法查证版权的或者未注明出处的均来自网络,系转载,转载的目的在于传递更多信息,版权属于原作者。如有侵权,请联系,笔者会第一时间删除处理!
3000+ 道 BAT 大厂面试题在线刷,最新、最全 Java 面试题!
Spring 源码分析(二)容器基本用法(系列文章基于Spring 5.0)
为什么很多公司强制弃坑 Fastjson 了?主推 Jackson
最近有很多人问,有没有读者交流群!想知道如何加入?方式很简单,兴趣相投的朋友,只需要点击下方卡片,回复“加群”,即可无套路入交流群!
文章有帮助的话,在看,转发吧。
谢谢支持哟 (*^__^*)