一直以来对这三者的的区别模棱两可说不出个所以然来,知其然不知其所以然。所以特意这次进行综合性的一次总结
在java中:
==是用算符。用来比较两个变量的值是否相等。
equals是Object类的方法。用于比较两个对象是否相等。默认比较的是两个对象的内存地址是否相等。跟==的比较结果是一样的。
hashCode()方法是从Object类中继承过来的。他也是用来比较两个对象的值是否相等,但是hashCode()方法返回的是该对象在内存地址中的hashcode值,是一个int型。如果对象没有重写hashcode()方法,那么所有对象都是不相等的。返回一个离散的int类型的值,在集合中更加有利于提高查询速度。如(hashMap、hashSet、hashSet)
有了以上三个概念那没就很好理解了:
java中可以分为两种数据类型:
基本数据类型:
1.基本数据类型,也称原始数据类型。byte,short,char,int,long,float,double,boolean
他们之间的比较,应用双等号(==),比较的是他们的内存值。
复合数据类型(类):
当我们使用做比较的时候,比较的是该对象在内存中的存放地址值。所以,除非是同一个new出来新的对象,他们比较返回的值为true ,否则返回false。java当中所有的类都继承Object这个基类。在object类定义一个equals方法,这个放法默认比较的是该对象的内存地址值,但是,一旦这个方法被覆盖了。那么这个方法的比较的就不再是该对象的内存地址值。 如(String、Integer、Date)这些类当中equals有其自身的实现
对于复杂数据类型的比较。在没有重写equals方法的情况下,还是比较的该对象在内存存放地址,因为equals方法也是引用( == ) 进行比较的,所以比较后的结果和比较后的结果是一样的。
如果比较两个对象的equals的值相等,那么这两个对象的hashcode值一定相等。
如果比较两个对象的equals的值不相等,那么这两个对象的hashCode值可能不相等。
从而在集合操作的时候有如下规则:
将对象放入集合中,首先要判断的是该对象的hashcode值是否与集合中已存在的元素的hashcode值是否相等。如果不相等,则直接把该对象放到集合中,如果相等,进一步判断该对象是否和集合中已存在的值equals是否相等,如果不相等,则直接把对象放到集合中,如果equals判断相等,那么就不放人集合。
回过来说get的时候,HashMap也先调key.hashCode()算出数组下标,然后看equals如果是true就是找到了,所以就涉及了equals。
a==b是在比较内存地址,hashCode是比较哈希值,就会出现以下几种情况:
a==b 则a.hashCode() == b.hashCode() 恒成立
a!=b 如果a.equals(b)==true 那么 a.hashCode()==b.hashCode() 恒成立
a!=b 如果a.equals(b)==false 那么 无法确定a.hashCode() b.HashCode() 是否相等
a.hashCode() == b.hashCode(),也无法推出ab或a.equals(b)