快速掌握Java初中級面試中的 == 和 equals 的必問考題

<head>/<head><body>

在Java的初中級面試中,總有這麼一題目它是那麼的耀眼,那麼堅強。它就是關於==和equals的區別是什麼?這個題目相信很多小夥伴都已經遇到過了,下面我們在本篇中使用通俗的介紹讓大家快速理解掌握。

== 是什麼?

在《java核心技術卷 1》中將==歸類於關係運算符;

==常用於相同的基本數據類型之間的比較,也可用於相同類型的對象之間的比較;

  • 如果==比較的是基本數據類型,那麼比較的是兩個基本數據類型的值是否相等;
  • 如果==是比較的兩個對象,那麼比較的是兩個對象的引用,也就是兩個對象是否為同一個對象,並不是比較的對象的內容;

下面舉例說明:

public class Test {
public static void main(String[] args){
// 對象比較
User userOne = new User();
User userTwo = new User();
System.out.println("userOne==userTwo : "+(userOne==userTwo));
// 基本數據類型比較
int a=1;
int b=1;
char c='a';
char d='a';
System.out.println("a==b : "+(a==b));
System.out.println("c==d : "+(c==d));
}
}

運行結果:

userOne==userTwo : false
a==b : true
c==d : true

總結 : 對象 userOne 和 userTwo 雖然都是 User 的實例,但對應了堆內存的不同區域,因此他們的引用也不同,所以為 false;a 和 b 都是基本類型因此對比的是值,結果為 true ; c 和 d 也是基本類型 同 a 和 b

equals 又是什麼呢?

在《java核心技術卷 1》中對 Object 類的描述:Object 類是java中所有類的始祖,在java中每個類都是由Object類擴展而來;每個類都默認繼承Object類,所以每一個類都有Object類中的方法;從而每一個類都有equals方法;

equals方法主要用於兩個對象之間,檢測一個對象是否等於另一個對象;

下邊來看一看Object類中equals方法的源碼:

public boolean equals(Object obj) {
return (this == obj);
}

可以看出來Object類中的equals方法用的還是==,也就是比較的兩個對象的引用是否相等,並不是根據對象中的屬性來判斷兩個對象是否相等的;也就是說我們自己定義的類中,如果沒有重寫equals方法,實際上還是用的==來比較的兩個對象,則用equals方法比較的結果與用==比較的結果是一樣的;

但是如果真的equals和==是一樣的,還有存在的必要嗎?

快速掌握Java初中級面試中的 == 和 equals 的必問考題


java語言規範要求equals方法具有以下特性:

  • 自反性 : 對於任意不為null的引用值x,x.equals(x)一定是true。
  • 對稱性 : 對於任意不為null的引用值x和y,當且僅當x.equals(y)是true時,y.equals(x)也是true。
  • 傳遞性 : 對於任意不為null的引用值x、y和z,如果x.equals(y)是true,同時y.equals(z)是true,那麼x.equals(z)一定是true。
  • 一致性 : 對於任意不為null的引用值x和y,如果用於equals比較的對象信息沒有被修改的話,多次調用時x.equals(y)要麼一致地返回true要麼一致地返回false。
  • 對於任意不為null的引用值x,x.equals(null)返回false。

既然java語言規範針對equals有那麼多要求,顯而易見,是想讓我們自己進行重寫的呢。

那麼怎麼重寫呢?

快速掌握Java初中級面試中的 == 和 equals 的必問考題

我們直接來看一下Java官方已經重寫的一個類,那就是String類。

public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}

從String底層源碼中我們可以看出,String類已經重寫了equals方法,那麼String就會根據其重寫的規則進行內容比較。下面我們再來舉個例子來看一下重寫equals方法後的String有什麼不同。

例子2 :

public class Test {
public static void main(String[] args){
// 未重寫equals方法的類
User userOne = new User();
User userTwo = new User();
System.out.println("userOne.equals(userTwo) : "+(userOne.equals(userTwo)));
//重寫了equals方法的類
String a="1111";

String b="1111";
System.out.println("a.equals(b) : "+(a.equals(b)));
}
}

測試結果:

userOne.equals(userTwo) : false
a.equals(b) : true

結論 : 雖然String是一個對象不是基本類型,但是由於String重寫了equals方法,所以仍然比較的值類型。

hashCode 又是什麼東西呢?

我們經常聽說在重寫完畢equals後就需要重寫hashCode方法,這是我們經常聽到的,但是很多小夥伴不知道為什麼。

hashCode也是Object類中的方法;下面看一下hashCode方法的源碼。該方法是一個本地方法;該方法返回對象的散列碼(int類型);它的實現是根據本地機器相關的。

public native int hashCode();

那麼這個方法返回的散列碼有什麼用呢?平時開發的時候也沒有注意到這個散列碼啊?

快速掌握Java初中級面試中的 == 和 equals 的必問考題

其實呢,這個問題很簡單,hashCode的散列碼在Java語言中是非常重要的。設想,如果你需要插入100個對象中到一個Set集合中,那麼在插入數據的時候肯定要和已經插入的數據進行比較是否相等,如果相等則不插入。(因為Set不允許重複嘛)。既然需要用到比較,那麼是調用equals進行比較嗎?不不不,當然不是,那樣效率該有多慢啊!

Java在將一個對象插入的集合中的時候,首先會調用該對象的hashCode方法獲取散列碼,將該散列碼與已經插入的對象的散列碼進行比較,如果沒有相同的散列碼,就說明沒有重複的。如果有相同的散列碼,則說明已經存在對象在該散列碼的hash鏈上,就會將相同散列碼的對象調用equals進行內容比較。

Java對於eqauls方法和hashCode方法是這樣規定的

  • 如果兩個對象相同,那麼它們的hashCode值一定要相同;
  • 如果兩個對象的hashCode相同,它們並不一定相同。
  • equals()相等的兩個對象,hashcode()一定相等;equals()不相等的兩個對象,卻並不能證明他們的hashcode()不相等。

例子 3:

public class Test {
public static void main(String[] args){
//未重寫hashCode的類
User userOne = new User("aa","11");
User userTwo = new User("aa","11");
System.out.println(userOne.hashCode());
System.out.println(userTwo.hashCode());
//重寫hashCode的類
String a = new String("string");
String b = new String("string");
System.out.println(a.hashCode());
System.out.println(b.hashCode());
}
}

測試結果 :

752848266 815033865 -891985903 -891985903

結論 : 根據結果可以看出:userOne 和 userTwo 的 hashCode 值不一致;a 和 b 的 hashCode 一致。

以上便是 == 和 equals 的區別,你都 Get 到了嗎?


你喜歡關於IT面試求職的相關內容嗎? (單選)
0人
0%
我很喜歡,請及時更新相關內容
0人
0%
我會留意,在我需要的時候
0人
0%
不感興趣
<button>投票/<button>


/<body>


分享到:


相關文章: