java中“==”、equals和hashCode的区别

时间:2020-12-23 16:12:01

1.“==”运算符是用来比较两个变量的值是否相等。也就是比较变量对应的内存中所存储的数值是否相同,要比较两个基本类型的数据或两个引用类型变量是否相等只能使用“==”来比较。
如果变量是基本数据类型,那么可直接用“==”比较。
例:

String s = "hello";
String t = "hello";
s==t;

返回的是true。

如果变量是指向数据的对象(引用类型),那么此时涉及到两块内存,对象本身占用一块内存空间(堆内存),变量也占用一块内存。
如:

String s = new String("hello");

变量s占用一块存储空间,而new String("hello")则存储在另一块存储空间里。此时,变量s的值就是new String("hello")占用内存的首地址。
例:

 String s = new String("hello");
String t = new String("hello");
s==t;

返回的是false。

2.equals是Object类提供的方法之一。每一个Java类都继承自Object类,所以每一个对象都具有equals这个方法。Object类中定义的equals(Object)方法是直接使用“==”运算符比较两个对象,所以在没有覆盖equals(Object)方法的情况下,equals(Object)和“==”一样,比较的是引用。

相比“==”运算符,equals(Object)方法的特殊之处在于它可以被覆盖,所以通过覆盖的方法让它比较数据内容而不是比较引用。如String类覆盖了equals(Object)方法(而StringBuffer的equals方法没有覆盖Object的方法),所以String类的equals()方法是用于比较两个独立对象的内容是否相同。
例如:

String s = new String("hello");
String t = new String("hello");
s==t;//s.equals(t);

返回的是false,而s.equals(t)将返回true。所以要比较量比较两个实例对象的内容是否相同,那你必须覆盖equals()方法,然后再进行比较。

3.hashCode()方法是从Object类中继承过来的,它也用来鉴定两个对象是否相等。Object类中的hashCode()方法返回对象是在内存中地址转换成的一个int值,所以如果没有重写hashCode()方法,任何对象的hashCode()方法都是不相等的。
既然说hashCode()也是用来鉴定两个对象是否相等,那么它和equals()方法有什么区别呢?
一般来说,equals()方法是给用户调用的,如果你想判断2个对象是否相等,你可以重写equals()方法,然后在代码中调用,就可以判断他们是否相等了。简单来讲,equals()方法主要是用来判断从表面上看或者从内容上看,2个对象是不是相等。举个例子,有个学生类,属性只有姓名和性别,那么我们可以认为只要姓名和性别相等,那么就说这2个对象是相等的。
hashCode()方法一般用户不会去调用它,比如在hashmap中,由于key是不可以重复的,它在判断key是不是重复的时候就判断了hashCode()这个方法,而且也用到了equals()方法。这里不可以重复是说equals()和hashCode()只要有一个不等就可以了!所以简单来讲,hashCode()相当于是一个对象的编码,就好像文件中的md5,它与equals()不同就在于他返回的是int型的,比较起来不直观。
一般在覆盖equals()的同时也要覆盖hashCode(),否则,就会违反Object.hashCode的通用约定,从而导致该类无法与所有基于散列值(hash)的集合类(HashMap、HashSet和Hashtable)结合在一起正常运行。
hashCode()方法的返回值和equals()方法发关系:

x.equals(y)
返回true,那么调用这2个对象中任意一个对象的hashCode()方法都必须产生同样的整数结果
返回false,那么x和y的hashCode()方法发返回值有可能相等,也有可能不想等。
反之,hashCode()方法返回值不相等,equals()方法返回值一定不相等。hashCode()方法返回值相等,equals()方法返回值可能相等,也可能不相等。