自定义对象需要重写hashcode
程序员文章站
2024-03-22 17:46:58
...
Java中的很多对象都override了equals方法,都知道,这是为了能比较两个对象是否相等而定义,如果不需要比较,则不需要定义equals方法。比如StringBuffer类,没有提供equals方法,则说明没有两个StringBuffer对象是相等的。再比如Collections类,全部是静态方法,根本没必要创建对象,所以也就没有提供equals方法。
我们程序中自定义的对象有时候需要比较它们是否相等,也需要重写equals方法。如果我们要将对象放到HashMap或者Hashtable这样的hash集合中的时候,就需要重写hashcode方法了。因为它们是根据hashcode来标识对象的。
如果我们不重写hashcode方法,把他们作为key放入hashmap中是什么情况呢?看看下面代码:
import java.util.HashMap;
public class HashTest {
public static void main(String...args) {
MyBean a = new MyBean();
a.x = 1;
a.s = "xyz";
MyBean b = new MyBean();
b.x = 1;
b.s = "xyz";
HashMap<MyBean, String> map = new HashMap<MyBean, String>();
map.put(a, "a");
map.put(b, "b");
System.out.println("a equals b:"+a.equals(b));
System.out.println("map size:"+map.size());
System.out.println("a:"+map.get(a));
System.out.println("b:"+map.get(b));
}
}
class MyBean {
int x;
String s;
@Override
public boolean equals(Object obj) {
if(this == obj) return true;
if(!(obj instanceof MyBean)) return false;
if(((MyBean)obj).x == x) return true;
return false;
}
}
结果如下:
a equals b:true
map size:2
a:a
b:b
a和b明明是相等的,可是放进hashmap中之后,却被认为是两个对象,很诡异哦。
下面加上hashcode,再看看什么结果:
class MyBean {
int x;
String s;
@Override
public boolean equals(Object obj) {
if(this == obj) return true;
if(!(obj instanceof MyBean)) return false;
if(((MyBean)obj).x == x) return true;
return false;
}
@Override
public int hashCode() {
return (s!=null?s.hashCode():1)*31+x;
}
}
结果如下:
a equals b:true
map size:1
a:b
b:b
这样才保证了相等的对象在hash集合中也相等。计算hashcode的时候,一般使用关键的属性的hashcode值。计算hashcode的属性较多则计算复杂,降低了效率,若较少的属性计算,则重复的hashcode较多,同样降低性能,写一个好的hashcode方法,还比较难。
所以,我们重写equals的时候,一定要重写hashcode方法。
推荐阅读
-
自定义对象需要重写hashcode
-
为什么重写 equals() 要重写 hashCode()? hashCode 值相等,两个对象不一定相等?
-
自定义对象重写hashCode和equals
-
java开发----自定义对象,重写equals方法
-
浅谈java中为什么重写equals后需要重写hashCode
-
为什么重写equals方法需要重写hashcode方法?
-
重写equal和hashCode方法,用集合去重对象
-
equals()方法和hashCode()方法是否需要同时重写
-
初级面试题:HashMap中对象作Key为什么要重写equals和hashcode?
-
重写自定义类的equals方法和hashcode方法