对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
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值