Java強調當重寫equals()時需要同時重寫hashcode()方法,假設兩個不同對象,在內存中的地址不同分別爲a和b,那麼重寫equals()以後a.equals(b) =true 開發者希望把a,b這兩個key視作完全相等
然而由於內存地址的不同導致hashcode不同,會導致在hashmap中儲存2個本應相同的key值;
如果不被重寫(原生)的hashCode和equals是什麼樣的?
1. 不被重寫(原生)的hashCode值是根據內存地址換算出來的一個值。
2. 不被重寫(原生)的equals方法是嚴格判斷一個對象是否相等的方法(object1 == object2)。
示例代碼demo1:
1. 沒有重寫equals
package com.compareObject;
/**
* @Auther: 13213
* @Date: 2020/5/26 14:22
* @Description:
*/
public class Dog {
private int age;
private String name;
public Dog(int age,String name){
this.age=age;
this.name=name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
// @Override
// public boolean equals(Object obj) {
// if(obj==null){
// return false;
// }
// if(this==obj){
// return true;
// }
// if(obj instanceof Dog){
// Dog dog=(Dog)obj;
// if(dog.age==this.age&&dog.name.equals(this.name)){
// return true;
// }else{
// return false;
// }
// }
// return false;
// }
public static void main(String[] args){
Dog dog1=new Dog(12,"wangcai");
Dog dog2=new Dog(12,"wangcai");
Dog dog3=new Dog(16,"wangcai");
System.out.println(dog1.equals(dog2));//true
System.out.println(dog1.equals(dog3));//false
}
}
運行結果:
2. 重寫equals
package com.compareObject;
/**
* @Auther: 13213
* @Date: 2020/5/26 14:22
* @Description:
*/
public class Dog {
private int age;
private String name;
public Dog(int age,String name){
this.age=age;
this.name=name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public boolean equals(Object obj) {
if(obj==null){
return false;
}
if(this==obj){
return true;
}
if(obj instanceof Dog){
Dog dog=(Dog)obj;
if(dog.age==this.age&&dog.name.equals(this.name)){
return true;
}else{
return false;
}
}
return false;
}
public static void main(String[] args){
Dog dog1=new Dog(12,"wangcai");
Dog dog2=new Dog(12,"wangcai");
Dog dog3=new Dog(16,"wangcai");
System.out.println(dog1.equals(dog2));//true
System.out.println(dog1.equals(dog3));//false
}
}
運行結果:
示例代碼demo2:
package com.compareObject;
import java.util.Collection;
import java.util.HashSet;
/**
* @Auther: 13213
* @Date: 2020/5/26 14:22
* @Description:
*/
public class Test {
public static void main(String[] args) {
Name n1 = new Name("zcj001");
Name n2 = new Name("zcj001");
Collection c = new HashSet();
c.add(n1);
c.add(n2);
System.out.println(n1.equals(n2));
System.out.println(n1.hashCode());
System.out.println(n2.hashCode());
System.out.println(c);
}
}
class Name {
private String id;
public Name(String id) {
this.id = id;
}
public String toString(){
return this.id;
}
public boolean equals(Object obj) {
if (obj instanceof Name) {
Name name = (Name) obj;
return (id.equals(name.id));
}
return super.equals(obj);
}
public int hashCode() {
return id.hashCode();
}
}
運行結果:
當只重寫equals()不重寫hashCode()運行結果如下:
示例代碼demo3:
package com.compareObject;
/**
* @Auther: 13213
* @Date: 2020/5/26 14:22
* @Description:
*/
public class Test {
public static void main(String[] args) {
String a = "123";
String b = "123";
System.out.println(a.equals(b));
System.out.println(a.hashCode());
System.out.println(b.hashCode());
}
}
運行結果:
此例說明,String對象重寫了equals()方法以及hashcode()方法,查看源代碼可知確實如此;