Course – LS – All

Get started with Spring and Spring Boot, through the Learn Spring course:

>> CHECK OUT THE COURSE

1. Overview

In this tutorial, we’ll understand the behavior of the Arrays mismatch() method. This method has three principal overloads, each available with a set of types. We’ll stick to int arrays for our examples.

2. The Base mismatch() Method

Let’s start with the simplest version of the mismatch() method.

2.1. Length of the Common Prefix

The mismatch() method takes two arrays and returns the index of the first different item between the arrays. For instance, {1, 2, 3, 4, 5} and {1, 2, 3, 5, 8} differ on index 3.

Let’s use JUnit5 to write a unit test to verify the method behaves as expected:

@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));
}

We can notice that if one array is a prefix of the other, the result is the length of the smallest array:

@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));
}

If the first element of the two arrays is different, the result is 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. Edge Cases

When the two arrays have the same elements in the same order, the method returns -1:

@Test
void givenTwoEmptyArrays_whenMismatch_thenMinusOne() {
    assertEquals(-1, Arrays.mismatch(new int[] {}, new int[] {}));
}

Let’s note that two empty arrays have no mismatch, so the result is also -1 in this case:

@Test
void givenTwoEmptyArrays_whenMismatch_thenMinusOne() {
    assertEquals(-1, Arrays.mismatch(new int[] {}, new int[] {}));
}

2.3. Null or Empty Array

However, if exactly one of the two arrays is empty, mismatch() returns the length of the empty array, i.e., 0:

@Test
void givenExactlyOneAnEmptyArray_whenMismatch_thenZero() {
    int[] firstArray = {};
    int[] secondArray = {1, 2, 3};
    assertEquals(0, Arrays.mismatch(firstArray, secondArray));
}

Last but not least, mismatch() throws a NullPointerException if any of the two arrays is null:

@Test
void givenAtLeastANullArray_whenMismatch_thenThrowsNullPointerException() {
    int[] firstArray = null;
    int[] secondArray = {1, 2, 3, 4, 5};
    assertThrows(NullPointerException.class, () -> Arrays.mismatch(firstArray, secondArray));
}

Finally, we can apply the mismatch() method to boolean, byte, char, short, int, long, float, double and Object arrays.

3. mismatch() With Subarrays

We’ll now focus on the method whose signature is, in the case of int arrays: int mismatch(int[] a, int aFromIndex, int aToIndex, int[] b, int bFromIndex, int bToIndex). This method variant extracts a subarray from each array then checks for mismatches.

3.1. Similar Behavior on Subarrays

Let’s see its behavior on an example:

@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));
}

Let’s understand what happens step by step:

  • first, the method computes the subarray between indexes 0 and 4 of the original first array {1, 2, 3, 4, 5}: the result is the new first array {1, 2, 3, 4}
  • it then calculates the subarray between indexes 1 and 6 of the original second array {0, 1, 2, 3, 5, 8}: the result is the array {1, 2, 3, 5, 8}
  • eventually, it applies the base mismatch() method to the two subarrays: {1, 2, 3, 4} and {1, 2, 3, 5, 8}; both start with {1, 2, 3} in that order, but the mismatch is on their 4th element

As a result, the method returns 4 in this case. Furthermore, all the points listed in the base version are valid for these variants:

  • if there is no mismatch, the method returns -1
  • if any array is null, the method throws a NullPointerException
  • this method is overriden with boolean, byte, char, short, int, long, float, double and Object arrays

3.2. Additional Exceptions

In addition to the standard behavior, the subarray method introduces new Exceptions. If, for any array, the “from” index is greater than the “to” index, mismatch() throws an 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));
}

Besides, if we pass an illegal index as an argument, the method throws an 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));
}

To sum up, the “from” index must be greater than 0, and the “to” index must be greater than the “from” index and lower than the arrays’ length.

4. Generic Method With Comparator

The last variant of the method takes two arrays of a generic type and computes the first mismatch given a Comparator. For instance, let’s take two String arrays and use the CASE_INSENSITIVE_ORDER Comparator from the String class:

@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));
}

All the points from the previous sections regarding edge cases and Exceptions are valid again. Furthermore, if the given Comparator is null, a NullPointerException is thrown as well:

@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));
}

Lastly, we can note that there is also an overridden method that works similarly with subarrays:

@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. Conclusion

In this article, we computed the first mismatch between two arrays. Java 9 introduced the mismatch() method for this purpose. We saw that this method is convenient in many cases because it offers a large set of overriding.

As always, the code is available over on GitHub.

Course – LS – All

Get started with Spring and Spring Boot, through the Learn Spring course:

>> CHECK OUT THE COURSE
res – REST with Spring (eBook) (everywhere)
Comments are open for 30 days after publishing a post. For any issues past this date, use the Contact form on the site.