Java相关规定
Java对于eqauls方法和hashCode方法是这样规定的:
(1)如果两个对象相同(equals方法返回true),那么它们的hashCode值一定要相同
(2)如果两个对象的hashCode相同,它们并不一定相同
当然,你未必要按照要求去做,但是如果你违背了上述原则就会发现在使用容器时,相同的对象可以出现在Set集合中,同时增加新元素的效率会大大下降(对于使用哈希存储的系统,如果哈希码频繁的冲突将会造成存取性能急剧下降)。
不遵循规定产生的后果
如果你自定义了一个对象,重写了equals方法,但没有重写hashcode方法,那么此时的equals为true但是hashcode为false,就会产生奇怪的现象。
package com.denk;
import java.util.HashSet;
import java.util.Set;
/**
* @author: denk
* desc:
* date: 2018/3/23
*/
public class Person {
public int age;
public String name;
public Person(int age, String name) {
this.age = age;
this.name = name;
}
@Override
public boolean equals(Object obj) {
Person p = (Person) obj;
return p.age == this.age && p.name.equals(this.name);
//return super.equals(obj);
}
public static void main(String[] args) {
Person a = new Person(1, "mike");
Person b = new Person(1, "mike");
System.out.println(a.hashCode() + "###" + b.hashCode());
System.out.println(a.equals(b));//打印为true
Set<Person> set = new HashSet<>();
set.add(a);
set.add(b);
System.out.println(set.size());//打印2
}
}
如上代码,重写了equals但没有重写hashcode,造成的结果就是在使用equals比较时两个对象是相等的。奇怪的现象产生了,因为set的size是2,说明两个相等的对象被添加到set中了。
所以在重写equals时一定要遵循Java的规定,同时重写hashcode
遵循规定同时重写equals和hashcode
package com.denk;
import java.util.HashSet;
import java.util.Set;
/**
* @author: denk
* desc:
* date: 2018/3/23
*/
public class Person {
public int age;
public String name;
public Person(int age, String name) {
this.age = age;
this.name = name;
}
@Override
public int hashCode() {
return 31 * this.age;
//return super.hashCode();
}
@Override
public boolean equals(Object obj) {
Person p = (Person) obj;
return p.age == this.age && p.name.equals(this.name);
//return super.equals(obj);
}
public static void main(String[] args) {
Person a = new Person(1, "mike");
Person b = new Person(1, "mike");
System.out.println(a.hashCode() + "###" + b.hashCode());
System.out.println(a.equals(b));//打印为true
Set<Person> set = new HashSet<>();
set.add(a);
set.add(b);//将会添加失败
System.out.println(set.size());//打印1
}
}
网友评论