Java中重写Object类的equals方法和 hashcode方法的注意事项

转载 2012年03月22日 18:40:37

 

在重写任何类的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
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
/**
 *
 * 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()便可以了。

 

object对象重写equals方法时为什么需要重写hashCode方法

在Java语言中,equals方法在使用时:     针对包装对象,比较的是对象的值(包括 boolean,byte,char,short,int,long,float,double)     针...
  • sinat_22013331
  • sinat_22013331
  • 2016年07月25日 17:16
  • 664

9. 【对于所有对象都通用的方法】重写equals方法时一定也要重写hashCode方法

本文是《Effective Java》读书笔记第9条:在每个覆盖了equals方法的类中,一定也要覆盖hasCode方法。否则会导致该类无法结合所有基于散列的集合一起正常工作。...
  • get_set
  • get_set
  • 2016年07月11日 23:01
  • 540

【Java基础之Object类(一)】Java中Object类中的所有方法(toString、equals、hashCode、clone、finalize、wait和notify等)详解

一、Object中所有方法简介: 在根类Object中包含一下方法:  clone();equals();finalize();getClass();[align=left][/align]noti...
  • cangchen
  • cangchen
  • 2015年04月10日 12:33
  • 1651

关于String类中重写Object类中的方法

Object作为所有类的基类,它里面定义了许多的方法,最为常见的就是hashCode()、equals()、toString()方法。 一、hashCode()方法 首先来看一下什么是哈希码(Ha...
  • wulianghuan
  • wulianghuan
  • 2013年02月22日 15:35
  • 4171

关于Object类的equals方法和hashCode方法

关于Object类的equals的特点,对于非空引用:1.自反性:x.equals(x) return true ;2.对称性:x.equals(y)为true,那么y.equals(x)也为true...
  • hahalzb
  • hahalzb
  • 2011年05月12日 17:43
  • 3764

Object类中的toString(),equals(), hashCode()方法之间的关系

1,在没有重写之前: (1)toString()方法返回的是对象的:Object 类的 toString 方法返回一个字符串,该字符串由类名(对象是该类的一个实例)、at 标记符“@”和此对象哈希码...
  • u014756517
  • u014756517
  • 2016年07月17日 22:36
  • 884

对于自定义类,重写equals方法和hashCode方法的技巧

参考:http://blog.csdn.net/fenglibing/article/details/8905007 对于自定义的类,如果要比较两个对象是否相同,就需要重写equals方法。举一个例...
  • Genius_zz
  • Genius_zz
  • 2016年09月16日 21:15
  • 4479

如何正确的重写equals() 和 hashCode()方法

equals和hashCode重写技巧
  • zzg1229059735
  • zzg1229059735
  • 2016年05月25日 15:36
  • 7424

Java中的equals和hashCode方法详解

Java中的equals方法和hashCode方法是Object中的,所以每个对象都是有这两个方法的,有时候我们需要实现特定需求,可能要重写这两个方法,今天就来介绍一些这两个方法的作用。 e...
  • jiangwei0910410003
  • jiangwei0910410003
  • 2014年04月01日 16:15
  • 54118

java Object对象中hashCode和equals方法学习

学习了多年的java的人对hashCode和equals方法都不是很清楚。 总的来说,Java中的集合(Collection)有两类,一类是List,另一类是Set。前者集合内的元素是有序的,元素可以...
  • lan12334321234
  • lan12334321234
  • 2017年04月11日 10:45
  • 426
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Java中重写Object类的equals方法和 hashcode方法的注意事项
举报原因:
原因补充:

(最多只允许输入30个字)