Java中檢查數組中的所有元素是否相等
1. 概述
在 Java 中使用陣列時,有時我們需要驗證數組中的所有元素是否相等。
在本教程中,我們將探討如何在 Java 中檢查數組中的所有元素是否相等。
2.問題介紹
檢查數組中的所有元素是否相等聽起來很簡單。然而,我們需要考慮一些邊緣情況,例如當數組為null或空時、當它只包含一個元素時、當它包含null值時等等。
此外,在Java中,我們有物件數組和原始數組。
在本教程中,我們將介紹這些場景。
讓我們先看看如何檢查物件數組的所有元素是否相等。
3. 物件數組
首先,讓我們列出一些元素相等或不相等的範例陣列:
// all-equal = true arrays:
final static String[] ARRAY_ALL_EQ = { "java", "java", "java", "java" };
final static String[] ARRAY_ALL_NULL = { null, null, null, null };
final static String[] ARRAY_SINGLE_EL = { "java" };
// all-equal = false arrays:
final static String[] ARRAY_NOT_EQ = { "java", "kotlin", "java", "java" };
final static String[] ARRAY_EMPTY = {};
final static String[] ARRAY_NULL = null;
如範例所示,如果陣列僅包含一個元素,我們認為所有元素都相等。但是,如果陣列為null或空,則它不包含任何元素。當然,它的元素並不相等。
接下來,讓我們將這些陣列作為輸入來建立不同的方法來執行檢查。
3.1.基於循環的通用方法
一個簡單的想法是在循環中檢查給定數組中的每個元素。為了使解決方案接受所有物件數組,我們可以使用通用方法:
<T> boolean isAllEqual(T[] array) {
if (array == null || array.length == 0) {
return false;
}
for (int i = 1; i < array.length; i++) {
if (!Objects.equals(array[0], array[i])) {
return false;
}
}
return true;
}
在isAllEqual()方法中,我們先檢查陣列是否為空或null並傳回預期結果 ( false ) 。然後,該方法透過將每個元素與第一個元素 ( array[0] ) 進行比較來檢查數組中的所有元素是否相等。如果任何元素不同,則方法傳回false ;否則,傳回true 。
值得一提的是,當我們比較元素值時,我們使用Objects.equals()而不是equals().這是因為**Objects.equals()靜態方法可以安全地處理null值並且不會引發NullPointerException** 。
接下來,讓我們用數組輸入來測試該方法:
assertTrue(isAllEqual(ARRAY_ALL_EQ));
assertTrue(isAllEqual(ARRAY_ALL_NULL));
assertTrue(isAllEqual(ARRAY_SINGLE_EL));
assertFalse(isAllEqual(ARRAY_NOT_EQ));
assertFalse(isAllEqual(ARRAY_EMPTY));
assertFalse(isAllEqual(ARRAY_NULL));
如果我們運行一下,測試就會通過。所以,我們的isAllEqual()解決了這個問題。
3.2.使用Stream的distinct()或allMatch()
Java 1.8 引進了一個重要的功能:Stream API。我們可以使用Arrays.stream(array)將陣列轉換為Stream ,然後使用Stream的便利方法來操作元素。
接下來,我們將使用Stream的distinct()和allMatch()方法解決這個問題。
distinct()可以從Stream中刪除重複元素。因此,如果所有元素都相等,則在distinct()之後我們將只有一個元素:
<T> boolean isAllEqualByDistinct(T[] array) {
// ... null and empty array handling
return Arrays.stream(array)
.distinct()
.count() == 1;
}
如示例所示,實現非常緊湊。以下測試顯示了distinct()方法可以完成這項工作:
assertTrue(isAllEqualByDistinct(ARRAY_ALL_EQ));
assertTrue(isAllEqualByDistinct(ARRAY_ALL_NULL));
assertTrue(isAllEqualByDistinct(ARRAY_SINGLE_EL));
assertFalse(isAllEqualByDistinct(ARRAY_NOT_EQ));
assertFalse(isAllEqualByDistinct(ARRAY_EMPTY));
assertFalse(isAllEqualByDistinct(ARRAY_NULL));
或者,我們也可以使用allMatch()來解決這個問題。 allMatch()方法檢查Stream中的所有元素是否與predicate函數相符:
<T> boolean isAllEqualByAllMatch(T[] array) {
// ... null and empty array handling
return Arrays.stream(array)
.allMatch(element -> Objects.equals(array[0], element));
}
這種方法通過了相同的測試:
assertTrue(isAllEqualByAllMatch(ARRAY_ALL_EQ));
assertTrue(isAllEqualByAllMatch(ARRAY_ALL_NULL));
assertTrue(isAllEqualByAllMatch(ARRAY_SINGLE_EL));
assertFalse(isAllEqualByAllMatch(ARRAY_NOT_EQ));
assertFalse(isAllEqualByAllMatch(ARRAY_EMPTY));
assertFalse(isAllEqualByAllMatch(ARRAY_NULL));
接下來,讓我們看看如何對原始數組執行相同的檢查。
4. 原始數組
我們已經看到了物件數組的不同解決方案。在本節中,我們以int[]為例來了解如何檢查原始陣列中的所有元素是否相等。
接下來,我們先建立一些輸入範例:
final static int[] INT_ARRAY_ALL_EQ = { 7, 7, 7, 7 };
final static int[] INT_ARRAY_SINGLE_EL = { 42 };
final static int[] INT_ARRAY_NOT_EQ = { 7, 7, 7, 42 };
我們省略了null和空數組輸入,因為與物件數組解決方案中的檢查沒有區別。此外,由於原始元素不會為null ,因此我們沒有「 ALL_NULL 」情況。
接下來,讓我們來看看如何對這些int[]陣列進行檢查。
4.1.使用循環
我們可以使用非常相似的基於循環的實作來檢查int[] :
boolean isAllEqual(int[] array) {
// ... null and empty array handling
for (int i = 1; i < array.length; i++) {
if (array[0] != array[i]) {
return false;
}
}
return true;
}
上面的程式碼看起來與通用isAllEqual()實作非常相似。但是,需要注意的是,我們應該使用「==」來檢查兩個基本變數的相等性。
值得一提的是,如果我們仍然使用Objects.equals()方法,該方法也有效,例如:
if (!Objects.equals(array[0], array[i])) {
return false;
}
讓我們仔細看看Objects.equals()方法:
public static boolean equals(Object a, Object b) {
return (a == b) || (a != null && a.equals(b));
}
如程式碼所示, Objects.equals()接受兩個Object實例。因此,當我們將int值傳遞給它時, int會**自動裝箱到其包裝類別****Integer** .因此,我們在解決方案中直接使用“ != ”檢查來避免不必要的自動裝箱。
我們的解決方案通過了測試:
assertTrue(isAllEqual(INT_ARRAY_ALL_EQ));
assertTrue(isAllEqual(INT_ARRAY_SINGLE_EL));
assertFalse(isAllEqual(INT_ARRAY_NOT_EQ));
要讓isAllEqual () 使用不同的基本類型,我們可以將參數類型**int[]**替換為所需的基本陣列**類型。**
4.2.使用Stream. distinct()或Stream.allMatch()
Java 提供了原始Stream類型,例如IntStream, LongStream等,它們允許我們使用原始值和Stream API,而無需在包裝器類型之間進行自動裝箱。
然而,由於沒有「 ShortStream 」類,我們可以使用Arrays.stream(shortArray)來取得Short實例的Stream 。
接下來,讓我們使用IntStream的distinct()和allMatch()來執行所需的檢查:
//distinct()
boolean isAllEqualByDistinct(int[] array) {
// ... null and empty array handling
return IntStream.of(array)
.distinct()
.count() == 1;
}
//test:
assertTrue(isAllEqualByDistinct(INT_ARRAY_ALL_EQ));
assertTrue(isAllEqualByDistinct(INT_ARRAY_SINGLE_EL));
assertFalse(isAllEqualByDistinct(INT_ARRAY_NOT_EQ));
//allMatch()
boolean isAllEqualByAllMatch(int[] array) {
// ... null and empty array handling
return IntStream.of(array)
.allMatch(element -> array[0] == element));
}
//test:
assertTrue(isAllEqualByAllMatch(INT_ARRAY_ALL_EQ));
assertTrue(isAllEqualByAllMatch(INT_ARRAY_SINGLE_EL));
assertFalse(isAllEqualByAllMatch(INT_ARRAY_NOT_EQ));
如程式碼所示,將參數類型變更為int[]使這些方法適用於int[]輸入。
5. 結論
在本文中,我們探索了檢查數組中所有元素是否相等的不同解決方案,並討論如何使用這些方法來檢查物件和原始數組。
與往常一樣,範例的完整原始程式碼可在 GitHub 上取得。