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 上取得。