Arrays Utility Class - Sip of Java
Billy Korando on May 1, 2023When needing to compare, copy, or sort arrays, a developer’s first instinct might be to write out the loops, if statements, and other logic necessary to handle this operation. This, in most cases, would be a mistake as it would be duplicating the behavior available in the java.util.Arrays
utility class. Let’s take a look at how to use the Arrays
class for handling everyday operations on arrays.
History of Arrays
The java.util.Arrays
was added to the JDK in 2, so it has been a while. It has seen several updates in subsequent releases. The most significant update was in JDK 8; the most recent update was with JDK 9. So if you are still on JDK 8, there might be a few changes you’re unfamiliar with.
Copying Arrays
Arrays
provides several options for copying an array with copy(T[], int length)
.
int[] numbers = new int[] {1,2,3,4,5};
int[] copyOfNumbers = Arrays.copyOf(numbers, numbers.length);
int[] copyOfSomeNumbers = Arrays.copyOf(numbers, numbers.length - 3);
int[] copyOfNumbersWithPadding = Arrays.copyOf(numbers, numbers.length + 1);
-
copyOfNumbers
- is an example of a simple copy of an array. -
copyOfSomeNumbers
- is an example of copying only a portion of an array. -
copyOfNumbersWithPadding
- is an example of copying an array and adding padding. The padded values are the default value for the type; in the case ofint
, that is 0.
Copying Subranges
Arrays
also provides an option for copying a specific subrange from an array with copyOfRange(T[]. int startIndex, int endIndex)
like in the example below:
int[] numbers = new int[] {1,2,3,4,5};
int[] copyOfNumbers = Arrays.copyOfRange(numbers, 0, 3);
System.out.println(Arrays.toString(numbers));//1,2,3,4,5
System.out.println(Arrays.toString(copyOfNumbers));//1,2,3
Converting Arrays to Other Types
Arrays
provides several methods for converting an array to a different type, including a List
, Stream
, Spliterator
, and String
:
int[] numbers = new int[] { 1, 2, 3, 4, 5 };
Arrays.asList(numbers);
Arrays.stream(numbers);
Arrays.spliterator(numbers);
Arrays.toString(numbers);
Comparing Arrays
For comparing arrays, Arrays
provides several options that often provide better results than default options. Let’s take a look:
int[] numbers = new int[] {1,2,3,4,5};
int[] copyOfNumbers = Arrays.copyOf(numbers, 5);
System.out.println(numbers.equals(copyOfNumbers));//False
System.out.println(Arrays.equals(numbers, copyOfNumbers));//True
In the above example, numbers
and copyOfNumbers
hold identical values, but int[].equals(int[])
returns the likely unexpected false
. This is because it is comparing by reference, not value. Whereas Arrays.equals(T[])
compares two arrays by the values stored in the arrays.
Comparing Subranges
Like with copying, Arrays
also has an option for comparing the subrange of arrays, like in this example:
int[] numbers = new int[] { 1, 2, 3, 4, 5 };
int[] moreNumbers = new int[] { 1, 2, 3, 6, 7 };
System.out.println(numbers.equals(moreNumbers));// False
System.out.println(Arrays.equals(numbers, moreNumbers));// False
System.out.println(Arrays.equals(numbers, 0, 2, moreNumbers, 0, 2));// True
Deep Comparison
When working with nested/multi-dimensional arrays, there is deepEquals(T[])
which step through the comparison of an array and any nested arrays:
int[][] coordinates = new int[][] { {10,20}, {100,200} };
int[][] altCoordinates = new int[][] { {10,20}, {100,200} };
System.out.println(coordinates.equals(altCoordinates));//False
System.out.println(Arrays.equals(coordinates, altCoordinates));//False
System.out.println(Arrays.deepEquals(coordinates, altCoordinates));//True
Comparing Comparable Arrays
Arrays
also allows comparing arrays containing primitive values and types implementing Comparable<T>
with compare(T[], T[])
:
int[] littleNumbers = new int[] {10, 20};
int[] copyOfLittleNumbers = Arrays.copyOf(littleNumbers, 2);
int[] bigNumbers = new int[] {100, 200};
System.out.println(Arrays.compare(littleNumbers, bigNumbers));//-1
System.out.println(Arrays.compare(bigNumbers, littleNumbers));//1
System.out.println(Arrays.compare(littleNumbers, copyOfLittleNumbers));//0
Sorting Arrays
For arrays containing primitives and types implementing Comparable<T>
, Arrays
can be used to sort the array with sort(T[])
. Arrays
can also only sort a subrange of an array with sort(T[], startIndex, endIndex)
. Note that Arrays
sorts the passed array; it doesn’t return a copy of a sorted array:
int[] numbers = new int[] { 3, 5, 2, 1, 4 };
int[] moreNumbers = new int[] { 3, 5, 2, 1, 4 };
System.out.println(Arrays.toString(numbers));// 3,5,2,1,4
Arrays.sort(numbers);
System.out.println(Arrays.toString(numbers));// 1,2,3,4,5
System.out.println(Arrays.toString(moreNumbers));// 3,5,2,1,4
Arrays.sort(moreNumbers, 0, 3);
System.out.println(Arrays.toString(moreNumbers));// 2,3,5,1,4
Searching Arrays
For sorted arrays, Arrays
also provides an operation for searching them with binarySearch(T[], T key)
returning the index if the key
is matched, -1
if the key
is below the range of the array, and the negative of the length of the array + 1 (i.e -6
if the array length is 5
) is return if the key is above range. Unsorted arrays will not return expected results. Below is an example of using binarySearch(T[], T key)
:
int[] numbers = new int[] { 1, 2, 3, 4, 5};
System.out.println(Arrays.binarySearch(numbers, 4)); // 3 - insertion point in array
System.out.println(Arrays.binarySearch(numbers, -0));// -1 - low value not in array
// (one less than 0)
System.out.println(Arrays.binarySearch(numbers, 8)); // -6 - high value not in array
// (negative value of length + 1)
Other Arrays Operations
There are several other operations Arrays
provides that aren’t covered in this article that are also worth checking out:
- deepHashCode(T[]) - Javadoc
- deepToString(T[]) - Javadoc
- fill(T[], T val) - Javadoc
- hashCode(T[]) - Javadoc
- mismatch(T[], T[]) - Javadoc
- parallelSort(T[]) - Javadoc
- parallelPrefix(T[] array, int fromIndex, int toIndex, BinaryOperator
o) - JavaDoc
Additional Reading
Happy coding!