欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

java中的==、equals和hashCode以及hashCode(摘)

程序员文章站 2022-07-10 10:45:50
...
文章摘抄自:http://jingyan.baidu.com/article/ff41162582507512e5823763.html
前言
    java中==、equals()、hashCode()都和对象的比较有关,在java中这三者各有什么用处呢,即java中为什么需要设计这三种对象的比较方法呢?
关于==
    ==是容易理解的。java设计java就是要比较两个对象是不是同一个对象。
    对于引用变量而言,比较的时候两个引用变量引用的是不是同一个对象,即比较的是两个引用中存储的对象地址是不是一样的。
    对于基本数据类型而言,比较的就是两个数据是不是相等,没什么歧义。
    由于对于基本数据类型而言,没有方法,所以不存在equal()和hashCode()的问题,下面的讨论都是针对引用类型而言的。
关于equals()
为什么java会设计equals()方法?
    ==比较的是两个对象是否是同一个对象,这并不能满足很多需求。有时候当两个对象不==的时候,我们仍然会认为两者是“相等”的,比如对于String对象,当两个对象的字符串序列是一直的,我们就认为他们是“相等”的。对于这样的需求,需要equals()来实现。对于有这种需求的对象的类,重写其equals()方法便可,具体的“相等”逻辑可以根据需要自己定义。
需要注意的地方
    Object中equals()的默认实现是比较两个对象是不是==,即其和==的效果是相同的。
   java提供的某些类已经重写了equals()方法。自己写的类,如果需要实现自己的“相等”逻辑,需要重写equals()方法。
关于hashCode()
为什么会设计hashCode()方法?
   hashCode()方法返回的就是一个数值,我们称之为hashCode吧。从方法的名称上就可以看出,其目的是生成一个hash码。hash码的主要用途就是在对对象进行散列的时候作为key输入,据此很容易推断出,我们需要每个对象的hash码尽可能不同,这样才能保证散列的存取性能。事实上,Object类提供的默认实现确实保证每个对象的hash码不同(在对象的内存地址基础上经过特定算法返回一个hash码)。
    分析到这个地方,看似没什么问题,三者的作用很清晰,好像他们之间也没什么关系。在java的规范上,hashCode()方法和equals()方法确实可以没有关系。
    但是!!!!!!!!有一个问题。
    问题如下:对于集合类HashSet、HashMap等和hash有关的类(以HashSet为例),是通过hash算法来散列对象的。对HashSet而言,存入对象的流程为:根据对象的hash码,经过hash算法,找到对象应该存放的位置,如果该位置为空,则将对象存入该位置;如果该位置不为空,则使用equals()比较该位置的对象和将要入的对象,如果两个相等,则不再插入,如果不相等,根据hash冲突解决算法将对象插入其他位置。
   而java规定对于HashSet判断是不是重复对象就是通过equals() 方法来完成,这就需要在两个对象equals()方法相等的时候,hash码一定相等(即hashCode()返回的值相等)。假设两个对象equals()方法相等的时候,hash码不相等,会出现equals()相等的两个对象都插入了HashSet中,这时不允许的。从而我们有了一下的结论:

    结论:对于equals()相等的两个对象,其hashCode()返回的值一定相等