对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
分享到:
相关推荐
equals()和hashcode()这两个方法都是从object类中继承过来的。当String 、Math、还有Integer、Double。。。。等这些封装类在使用equals()方法时,已经覆盖了object类的equals()方法.
HashCode相同equals不同的2位字符集合算法 另附ASCII码表
本文档详细介绍了set接口为什么会用到hashCode和equals方法以及这两个方法的一些探讨 set不同的实现类用到的这两个方法也不同
java中hashcode和equals的详解.pdf
在这篇文章中,我将告诉大家我对hashCode和equals方法的理解。我将讨论他们的默认实现,以及如何正确的重写他们。我也将使用Apache Commons提供的工具包做一个实现。 hashCode()和equals()定义在Object类中,这...
关于hashCode()和equals()的本质区别和联系.doc
有许多人学了很长时间的Java,但一直不明白hashCode方法的作用,我来解释一下吧。首先,想要明白hashCode的作用,你必须要先知道Java中的集合。
主要介绍了重写hashCode()和equals()方法详细介绍,涉及重写equals()方法,重写hashCode()方法,重写equals()而不重写hashCode()的风险等相关内容的介绍,具有一定借鉴价值,需要的朋友可以参考下
重写equals和hashcode方法,学习和进步
hashcode、equals、==总结1简单总结.txt,他们之间的区别
本文还介绍了定义对象的相等性、实施equals()和hashCode()的需求、编写自己的equals()和hashCode()方法。通过统一定义equals()和hashCode(),可以提升类作为基于散列的集合中的关键字的使用性。
更清楚的了解hashcode()和equals()方法。
hashcode()和equals() 博客地址:https://blog.csdn.net/qq_36963950/article/details/107543471
Java重写equals同时需要重写hashCode的代码说明,以及如何重写hashCode方法,此代码演示按照effective java书籍说明的重写思路。代码中演示了使用集合存储对象,并且对象作为key,需重写equals和hashCode.
这里是一个文档,里边讲解了hashCode与equals方法使用,大家要是不明白,可以去看看
文章目录1、hashCode与equals两者之间的关系2、== 和equals的区别`3、为什么要重写equals()方法?4、重写equals()方法5、为什么要重写hashCode()方法?6、什么时候需要重写hashCode()方法?7、重写hashCode()方法: ...
NULL 博文链接:https://zpointer.iteye.com/blog/1058337
hashCode()和equals()定义在Object类中,这个类是所有java类的基类,所以所有的java类都继承这两个方法。下面这篇文章主要给大家介绍了关于java中hashCode、equals的使用方法,需要的朋友可以参考下。
在Java中,equals和hashCode方法是Object中提供的两个方法,这两个方法对以后的学习有很大的帮助,本文就深度来去讲解这两个方法。下面小编带大家来一起学习吧
主要介绍了详解hashCode()和equals()的本质区别和联系,本文先对两种方法作了介绍,然后对二者联系进行分析,具有一定参考价值,需要的朋友可以了解下。