对hashcode和equals的深度理解

对hashcode和equals的深度理解

---》一个例子
public class Student
{
	private int id; 
	private String name;
	public int getId()
	{
		return id;
	}
	public void setId(int id)
	{
		this.id = id;
	}
	public String getName()
	{
		return name;
	}
	public void setName(String name)
	{
		this.name = name;
	}
	
	public static void main(String[] args)
	{
		Student s1 = new Student();
		s1.setId(1);
		Student s2 = new Student();
		s2.setId(1);
		System.out.println(s1.equals(s2)); //false
		
	}
}

---》未重写hashcode和equals方法情况
System.out.println(s1.equals(s2)); //false
打印了false,因为是生成了两个对象,调用Object的equals方法,默认直接比对两个对象的地址是否一样。
---》只重写equals方法情况(eclipse生成)
现在有个业务逻辑认为id相同,就认为是同一个学生,故加入了equals方法,如下:

	@Override
	public boolean equals(Object obj)
	{
		if (this == obj) return true;
		if (obj == null) return false;
		if (getClass() != obj.getClass()) return false;
		Student other = (Student) obj;
		if (id != other.id) return false;
		return true;
	}

System.out.println(s1.equals(s2)); //true

现在又有个需求,把生成的学生放入set中
Set<Student> set  = new HashSet<Student>();
set.add(s1);
set.add(s2);
System.out.println(set.size());//2
System.out.println(s1.hashCode() == s2.hashCode());//false
既然s1和s2 id相同,equals已经相等了,结果却是2,要知道set是不能放入重复对象的,重写hashcode再试一下。
---》重写hashcode方法情况(eclipse生成)
	@Override
	public int hashCode()
	{
		final int prime = 31;
		int result = 1;
		result = prime * result + id;
		return result;
	}
	System.out.println(set.size());//1
	System.out.println(s1.hashCode() == s2.hashCode());//true

---》结论
* 业务逻辑重新定义对象是同一对象时,两个方法必须同时重写。
* 在object类中,hashcode()方法是本地方法,返回的是对象的地址值,而object类中的equals()方法比较的也是两个对象的地址值;
* equals相等 则hashcode()相等,hashcode()相等,equals不一定相等;
* 没有写equals方法,调用时会调用Object的equals方法,默认就是直接比对两个对象的地址是否一样,即this == obj。
* 用到HashMap或者HashSet时,将其内容作为"是否重复"的标准(而不是按内存地址比较),则需要自己重写这两个方法。
* HashMap或者HashSet时比对过程:首先根据hash值定位到某个区域上,然后再在区域内进行equals判断,效率高。
* 将对象的属性值参与了hashCode的运算中,在进行删除的时候,就不能对其属性值进行修改,否则会出现严重内存泄露问题,所以尽量保证使用对象的同一个属性来生成hashCode()和equals()两个方法。

参考:
http://blog.csdn.net/whuslei/article/details/6686612
http://blog.csdn.net/jiangwei0910410003/article/details/22739953
http://blog.csdn.net/steveguoshao/article/details/12576849
http://stackoverflow.com/questions/3613102/why-use-a-prime-number-in-hashcode

猜你喜欢

转载自ynp.iteye.com/blog/2232839