在 Java 中比較兩個字節數組
一、概述
在 Java 中,當我們要比較兩個byte
數組時,如果比較不當,可能會得到意想不到的結果。
因此,在本快速教程中,我們將學習比較兩個數組值的正確方法。
二、問題介紹
舉個例子可以很快說明問題。假設我們有一個字符串:
final static String INPUT = "I am a magic string.";
現在,我們通過String.getBytes()
方法從上面的字符串中獲取兩個字節數組:
final static byte[] ARRAY1 = INPUT.getBytes();
final static byte[] ARRAY2 = INPUT.getBytes();
顯然,如果我們比較ARRAY1
和ARRAY2,
我們希望這兩個數組的值相等,因為它們是從相同的輸入字符串創建的。
那麼接下來,讓我們看看我們可能會犯哪些常見錯誤,並找出進行比較的正確方法。
為簡單起見,我們將使用單元測試斷言來驗證每種比較方法是否返回預期結果。
3. == 運算符和equals()
方法不是好的選擇
在 Java 中,== 被稱為“等於”運算符。所以首先,讓我們嘗試使用==
運算符比較兩個數組:
assertFalse(ARRAY1 == ARRAY2);
上面的簡單測試在我們運行時通過了。也就是說, ARRAY1 == ARRAY2
返回false
,即使兩個數組中的元素的值相同——這不是我們想要的結果。這是因為== 運算符比較的是兩個數組的內存地址而不是它們的內容。這意味著兩個數組可以具有相同的內容,但它們是不同的對象。因此,== 運算符將返回false
,即使兩個數組是等價的。
我們可能已經了解了 == 運算符和 Java 中的equals()
方法之間的區別:== 執行引用相等性檢查,而equals()
方法執行值相等性檢查。
由於我們的目標是比較兩個數組的值,讓我們創建另一個簡單的測試來使用equals()
方法比較ARRAY1
和ARRAY2
:
assertFalse(ARRAY1.equals(ARRAY2));
如果我們運行這個測試,它也會通過。這意味著**equals()
方法也沒有給我們預期的結果**。接下來,讓我們弄清楚為什麼equals()
不能正確完成工作。
當我們調用ARRAY1.equals(ARRAY2)
時,實際上調用了Object
類的equals()
方法。那麼,讓我們看一下Object
類的equals()
方法的實現:
public boolean equals(Object obj) {
return (this == obj);
}
正如我們所見, Object
的equals()
方法在內部使用 == 運算符比較兩個對象。當我們比較數組時,== 和equals()
是相同的。因此,它們都執行引用相等性檢查。
4. 使用Arrays.equals()
方法
現在,我們明白 == 運算符和equals()
方法都不是檢查兩個數組值相等性的正確方法。但是,兩個數組的值比較是 Java 編程中非常常見的操作。因此,Java 標準庫提供了Arrays.equals()
方法來完成這項工作:
assertTrue(Arrays.equals(ARRAY1, ARRAY2));
如果我們試一試,測試就會通過。因此, Arrays.equals()
返回比較我們的兩個byte
數組的預期結果。
此外, Arrays.equals()
適用於其他類型的數組。我們應該使用Arrays.equals()
方法來檢查所有數組類型的值是否相等。
最後再看一個兩個String
數組的值比較例子:
String[] strArray1 = new String[] { "Java", "is", "great" };
String[] strArray2 = new String[] { "Java", "is", "great" };
assertFalse(strArray1 == strArray2);
assertFalse(strArray1.equals(strArray2));
assertTrue(Arrays.equals(strArray1, strArray2));
在上面的代碼中, strArray1
和strArray2's
內容是相同的。測試結果顯示==
和equals()
報告false,
但使用Arrays.equals()
方法給出了預期的結果。
5.結論
在本文中,我們討論了比較兩個數組內容時的常見陷阱。此外,我們還探討了比較兩個byte
數組值的正確方法。
== 運算符和equals()
方法都對數組執行引用相等性檢查。如果我們需要比較兩個數組的值, Arrays.equals(array1, array2)
方法是正確的方法。
與往常一樣,此處提供的所有代碼片段都可以在 GitHub 上找到。