在重写任何类的equals方法是必须遵循以下几点:
1、对称性:如果x.equals(y)返回是“true”,那么y.equals(x)也应该返回是“true”。
2、反射性:x.equals(x)必须返回是“true”。
3、类推性:如果x.equals(y)返回是“true”,而且y.equals(z)返回是“true”,那么z.equals(x)也应该返回是“true”。
4、还有一致性:如果x.equals(y)返回是“true”,只要x和y内容一直不变,不管你重复x.equals(y)多少次,返回都是“true”。
5、任何情况下,x.equals(null),永远返回是“false”;
在重写任何类得hashcode方法是必须遵循以下几点:
1、在Java应用的同一次执行过程中,同一对象被多次调用,则他们的hashcode值必然相同。而对于同一个应用的两次不同的调用,它们的Hashcode值可以相同,也有可能不同。
2、对于两个对象来说,如果他们的equals方法比较返回true,那么这两个对象的hashcode必然相同。这也解释了为什么String类中,如果两个对象的equals方法相同,则他们的hashcode值一定相同。
3、对于两个对象来说,如果使用equals方法返回为false,则他们的hashcode的值有可能相等也可能不等,(如果不同会提高性能,因为在集合中类判断两个对象是否相等,如果其hashcode不等就直接不用判断equals方法了)
4、对于Object对象来说,不同的Object对象的hashcode是不同的,它们返回的是对象的地址,equals返回的也是对象的地址。所以在自己定义的类中如果要添加到集合对象中,最好是要重写hashcode和equals方法,不然会自动继承自Object类中的两个方法根据对象地址来判断。在重写自己定义的类时,通常是在类中的根据某个值如name.hashcode();来进行判断。
以HashSet 为例,
- /**
- *
- * People 手工重写hashcode方法和equals方法 根据name来判断 两个对象是否相等。
- * 2011-7-12 上午09:09:56
- *
- * @version 1.0.0
- *
- */
- class People {
- private String name;
- public People(String name){
- this.name=name;
- }
- @Override
- public boolean equals(Object obj) {
- // TODO Auto-generated method stub
- //如果是自己
- if(this==obj){
- return true ;
- }
- //如果是空
- if(obj==null ){
- return false;
- }
- //比较两个People的名字是否相同
- if(obj!=null && obj instanceof People){
- if(((People)obj).name.equals(this.name))
- return true ;
- }
- return false;
- }
- @Override
- public int hashCode() {
- // TODO Auto-generated method stub
- //String的hashcode本来就是用来比较两个字符是否相等
- return name.hashCode();
- }
- }
其他相关问题:
那么在String中的hashcode是怎么定义的呢?在String的API中我们可以看到这样一个公式: s[0]*31^(n-1) + s[1]*31^(n-2) + … + s[n-1] 使用int 算法,这里s[i] 是字符串的第i 个字符,n 是字符串的长度,^ 表示求幂。(空字符串的哈希码为0。)这说明String 中的hashcode 返回的并不是在内存中的地址,如果两个字符串的内容相同(equals为true),则其hashcode值必然就相同,equal为true。同理经过傻蛋测试在Integer类中和String类似,hashcode方法和equals方法也是判断其包裹的原始值的内容是否相同。
总结:在Java中,String 、Math、还有Integer、Double。。。。等这些封装类重写了Object中的equals()方法,让它不再比较其对象在内存中的地址,而是比较对象中实际包含的整数的值,即比较的是内容。再强调一次,Object的equals()方法比较的是地址值,所以Object equals相等时,其hashcode必然相等,因为都是对象的地址,所以自己定义的类如果要加入到集合类中一定要记得重写这两个方法。
在Eclipse中重写hashcode和equals方法使相当方便的,只需要右键->source->Generate hashcode() and equals()便可以了。
本文转自 最牛傻蛋 51CTO博客,原文链接:http://blog.51cto.com/zuiniuwang/719907,如需转载请自行联系原作者