java中重写Object类的equals方法和Hashcode方法的注意事项

简介:

在重写任何类的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 为例,

 

 
当我们使用HashSet时,hashCode()方法就会被得到调用,判断已经存储在集合中的对象的hashCode值是否与所增加
 

 

 
对象的hashCode值一致,如果“不一致”则直接加进去(不用比较equals()提高效率),如果一致,则进行equals方法的比较,如果返回true,表明
 
集合里面已经有这个对象,不能添加进去了。如果是false表是集合里面没有这个对象,则可以加进去。所以我们在重写hashcode()或者equals()
 
方法的任何一个方法时,必须重写另外一个。
 
自己手工写了一个类来重写这两个方法:
 
 
  1. /**  
  2.  *  
  3.  * People  手工重写hashcode方法和equals方法  根据name来判断 两个对象是否相等。  
  4.  * 2011-7-12 上午09:09:56  
  5.  *  
  6.  * @version 1.0.0  
  7.  *  
  8.  */  
  9. class People {  
  10.     private String name;  
  11.    
  12.     public People(String name){  
  13.         this.name=name;  
  14.     }  
  15.     @Override  
  16.     public boolean equals(Object obj) {  
  17.    
  18.         // TODO Auto-generated method stub  
  19.         //如果是自己  
  20.         if(this==obj){  
  21.             return true ;  
  22.    
  23.         }  
  24.         //如果是空  
  25.         if(obj==null ){  
  26.             return false;  
  27.         }  
  28.         //比较两个People的名字是否相同  
  29.         if(obj!=null && obj instanceof People){  
  30.             if(((People)obj).name.equals(this.name))  
  31.                 return  true ;  
  32.    
  33.         }  
  34.         return false;  
  35.    
  36.     }  
  37.    
  38.     @Override  
  39.     public int hashCode() {  
  40.    
  41.         // TODO Auto-generated method stub  
  42.         //String的hashcode本来就是用来比较两个字符是否相等  
  43.         return  name.hashCode();  
  44.    
  45.     }  
  46.    

其他相关问题:

那么在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,如需转载请自行联系原作者

相关文章
|
24天前
|
Java
java equals和==
==是进行对象的地址值比较,如果确实需要字符串的内容比较,可以使用两个方法 public boolean equals(0bjectobj):参数可以是任何对象,只有参数是一个字符串并且内 容相同的才会给true;否则返回false 注意事项: 1.任何对象都能用object进行接收。 2.equals方法具有对称性,也就是a.equals(b)和b.equals(a)效果一样。 3.如果比较双方一个常量一个变量,推荐把常量字符串写在前面。 推荐:"abc".equals(str) 不推荐:str.equals("abc") public boolean egualsIgnoreCas
8 1
|
1月前
|
存储 设计模式 Python
Python中的类(Class)和对象(Object)
Python中的类(Class)和对象(Object)
27 0
|
1月前
|
Java
Java中常见需要重写equals方法的类
Java中常见需要重写equals方法的类
|
2月前
|
Java 流计算
在Flink实时任务中,POJO(Plain Old Java Object)对象的模式演进可能会引起不兼容的问题
【2月更文挑战第6天】在Flink实时任务中,POJO(Plain Old Java Object)对象的模式演进可能会引起不兼容的问题
19 3
|
3月前
|
Python
Python学习 -- 根类object
Python学习 -- 根类object
16 0
|
3月前
|
Java
Java中 ==与equals的区别
Java中 ==与equals的区别
16 1
|
3月前
|
消息中间件 Java Kafka
Kafka - java.lang.VerifyError: Uninitialized object exists on backward branch 193
Kafka - java.lang.VerifyError: Uninitialized object exists on backward branch 193
50 0
|
4月前
|
Java
JAVA中比较对象是否相等的方式是什么?为什么重写equals就一定要重写hashcode?百天百题(3/100)
JAVA中比较对象是否相等的方式是什么?为什么重写equals就一定要重写hashcode?
|
5月前
|
Java
java判断Object对象是否为空demo
java判断Object对象是否为空demo
|
7天前
|
JavaScript
js 字符串String转对象Object
该代码示例展示了如何将一个以逗号分隔的字符串(`'1.2,2,3,4,5'`)转换为对象数组。通过使用`split(',')`分割字符串并`map(parseFloat)`处理每个元素,将字符串转换成浮点数数组,最终得到一个对象数组,其类型为`object`。