Java 中的陣列 Mismatch() 方法
1. 概述
在本教程中,我們將了解Arrays mismatch()
方法的行為。此方法有三個主要重載,每個重載都有一組類型。我們將堅持使用int
數組作為範例。
2. Base Mismatch() 方法
讓我們從最簡單版本的mismatch()
方法開始。
2.1.公共前綴的長度
mismatch()
方法接受兩個陣列並傳回數組之間第一個不同項的索引。例如, {1, 2, 3, 4, 5}
和{1, 2, 3, 5, 8}
在索引3
上不同。
讓我們使用 JUnit5 編寫一個單元測試來驗證該方法的行為是否符合預期:
@Test
void givenTwoArraysWithACommonPrefix_whenMismatch_thenIndexOfFirstMismatch() {
int[] firstArray = {1, 2, 3, 4, 5};
int[] secondArray = {1, 2, 3, 5, 8};
assertEquals(3, Arrays.mismatch(firstArray, secondArray));
}
我們可以注意到,如果一個陣列是另一個陣列的前綴,則結果是最小陣列的長度:
@Test
void givenFirstArrayIsAPrefixOfTheSecond_whenMismatch_thenFirstArrayLength() {
int[] firstArray = {1, 2, 3, 4, 5};
int[] secondArray = {1, 2, 3, 4, 5, 6, 7, 8, 9};
assertEquals(firstArray.length, Arrays.mismatch(firstArray, secondArray));
}
如果兩個陣列的第一個元素不同,則結果為0
:
@Test
void givenNoCommonPrefix_whenMismatch_thenZero() {
int[] firstArray = {1, 2, 3, 4, 5};
int[] secondArray = {9, 8, 7};
assertEquals(0, Arrays.mismatch(firstArray, secondArray));
}
2.2.邊緣情況
當兩個數組具有相同順序的相同元素時,此方法傳回-1
:
@Test
void givenTwoEmptyArrays_whenMismatch_thenMinusOne() {
assertEquals(-1, Arrays.mismatch(new int[] {}, new int[] {}));
}
請注意,兩個空數組沒有不匹配,因此在這種情況下結果也是-1
:
@Test
void givenTwoEmptyArrays_whenMismatch_thenMinusOne() {
assertEquals(-1, Arrays.mismatch(new int[] {}, new int[] {}));
}
2.3.空數組
但是,如果兩個陣列中恰好有一個為空, mismatch()
傳回空數組的長度,即0
:
@Test
void givenExactlyOneAnEmptyArray_whenMismatch_thenZero() {
int[] firstArray = {};
int[] secondArray = {1, 2, 3};
assertEquals(0, Arrays.mismatch(firstArray, secondArray));
}
最後但並非最不重要的一點是,如果兩個陣列中的任何一個為 null mismatch()
就會拋出NullPointerException
null:
@Test
void givenAtLeastANullArray_whenMismatch_thenThrowsNullPointerException() {
int[] firstArray = null;
int[] secondArray = {1, 2, 3, 4, 5};
assertThrows(NullPointerException.class, () -> Arrays.mismatch(firstArray, secondArray));
}
最後,我們可以將mismatch()
方法套用到boolean, byte, char, short, int, long, float, double
和Object
數組。
3. Mismatch() 與子數組
我們現在將重點放在其簽章的方法,在int
數組的情況下: int mismatch(int[] a, int aFromIndex, int aToIndex, int[] b, int bFromIndex, int bToIndex)
。此方法變體**從每個數組中提取一個子數組,然後檢查是否不匹配。**
3.1.子數組上的類似行為
讓我們透過一個例子來看看它的行為:
@Test
void givenTwoSubArraysWithACommonPrefix_whenMismatch_thenIndexOfFirstMismatch() {
int[] firstArray = {1, 2, 3, 4, 5};
int[] secondArray = {0, 1, 2, 3, 5, 8};
assertEquals(3, Arrays.mismatch(firstArray, 0, 4, secondArray, 1, 6));
}
讓我們逐步了解發生了什麼:
- 首先,此方法計算原始第一個陣列
{1, 2, 3, 4, 5}
的索引0
和4
之間的子陣列:結果是新的第一個陣列{1, 2, 3, 4}
- 然後計算原始第二個數組
{0, 1, 2, 3, 5, 8}
的索引1
和6
之間的子數組:結果是數組{1, 2, 3, 5, 8}
- 最終,它將基本的
mismatch()
方法應用於兩個子數組:{1, 2, 3, 4}
和{1, 2, 3, 5, 8}
;兩者都按順序以{1, 2, 3}
開頭,但不匹配的是它們的第四個元素
因此,在本例中該方法傳回4
。此外,基本版本中列出的所有要點對於這些變體都有效:
- 如果沒有不匹配,則該方法返回
-1
- 如果任何數組為空,該方法將拋出
NullPointerException
- 此方法被
boolean, byte, char, short, int, long, float, double
和Object
數組覆蓋
3.2.其他例外情況
除了標準行為之外,子數組方法還引入了新的Exception
。對於任何數組,如果「from」索引大於「to」索引, mismatch()
會拋出IllegalArgumentException
:
@Test
void givenToIndexGreaterThanFromIndex_whenMismatch_thenThrowsIllegalArgumentException() {
int[] firstArray = {2, 3, 4, 5, 4, 3, 2};
int[] secondArray = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
assertThrows(IllegalArgumentException.class, () -> Arrays.mismatch(firstArray, 4, 2, secondArray, 0, 6));
}
此外,如果我們傳遞非法索引作為參數,則該方法會拋出ArrayIndexOutOfBoundsException
:
@Test
void givenIllegalIndexes_whenMismatch_thenThrowsArrayIndexOutOfBoundsException() {
int[] firstArray = {2, 3, 4, 5, 4, 3, 2};
int[] secondArray = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
assertThrows(ArrayIndexOutOfBoundsException.class, () -> Arrays.mismatch(firstArray, -1, 2, secondArray, 0, 6));
}
總而言之,「from」索引必須大於0
,「to」索引必須大於「from」索引並小於陣列長度。
4. 帶有比較器的通用方法
此方法的最後一個變體採用兩個泛型類型的數組,並計算給定Comparator
第一個不匹配。例如,我們採用兩個String
陣列並使用String
類別中的CASE_INSENSITIVE_ORDER Comparator
:
@Test
void givenTwoStringArraysAndAComparator_whenMismatch_thenIndexOfFirstMismatch() {
String[] firstArray = {"one", "two", "three"};
String[] secondArray = {"ONE", "TWO", "FOUR"};
Comparator<String> comparator = String.CASE_INSENSITIVE_ORDER;
assertEquals(2, Arrays.mismatch(firstArray, secondArray, comparator));
}
前面部分中有關邊緣情況和Exceptions
所有要點再次有效。此外,如果給定的Comparator
為null
,也會引發NullPointerException
:
@Test
void givenAtLeastANullArrayOrNullComparator_whenMismatch_thenThrowsNullPointerException() {
String[] firstArray = {"one"};
String[] secondArray = {"one"};
Comparator<String> comparator = String.CASE_INSENSITIVE_ORDER;
assertThrows(NullPointerException.class, () -> Arrays.mismatch(firstArray, secondArray, null));
}
最後,我們可以注意到還有一個與子數組類似的重寫方法:
@Test
void givenTwoStringSubarraysAndAComparator_whenMismatch_thenIndexOfFirstMismatch() {
String[] firstArray = {"one", "two", "three", "four"};
String[] secondArray = {"ZERO", "ONE", "TWO", "FOUR", "EIGHT", "SIXTEEN"};
Comparator<String> comparator = String.CASE_INSENSITIVE_ORDER;
assertEquals(2, Arrays.mismatch(firstArray, 0, 4, secondArray, 1, 3, comparator));
}
5. 結論
在本文中,我們計算了兩個陣列之間的第一個不匹配。 Java 9 為此引進了mismatch()
方法。我們發現這種方法在許多情況下都很方便,因為它提供了大量的重寫。
與往常一樣,程式碼可以在 GitHub 上取得。