Java Arrays Class
Java’s built-in array type is deliberately bare-bones: it stores a fixed-size sequence of elements and gives you almost no methods to work with. The java.util.Arrays class fills that gap. It is a utility class full of static methods for sorting, searching, comparing, filling, copying, and printing arrays, so you rarely need to hand-write these operations yourself. Understanding it well means you spend less time reinventing loops and more time writing the logic that actually matters.
This lesson covers the most important methods on java.util.Arrays, how they behave internally, and the mistakes beginners commonly make when using them.
Overview / How it works
Arrays lives in the java.util package, so you must import it with import java.util.Arrays; before using it. It is a final class with a private constructor, meaning you can never instantiate it—every method is called directly on the class name, like Arrays.sort(myArray). This is the same design pattern used by Math and Collections: a stateless bag of static helper methods.
Internally, most Arrays methods operate directly on the array’s underlying memory block. Java arrays are objects stored on the heap with a fixed length determined at creation time and a contiguous block of memory holding the elements. When you call Arrays.sort(arr), the JVM does not create a new array—it rearranges the elements in place inside that same memory block. Methods like Arrays.copyOf, on the other hand, allocate a brand-new array and copy elements into it, leaving the original untouched. Knowing which category a method falls into (mutates in place vs. returns a new array) is essential to avoid subtle bugs.
Arrays is heavily overloaded: nearly every method has a version for int[], double[], long[], char[], boolean[], and Object[] (which covers String[], custom classes, etc.). The compiler picks the right overload automatically based on the array’s declared type.
Syntax
There is no single “syntax” for a utility class—instead you call individual static methods. The general form is:
Arrays.methodName(array, [otherArguments...]);
| Method | Purpose |
|---|---|
Arrays.sort(arr) |
Sorts the array in place, ascending order |
Arrays.sort(arr, comparator) |
Sorts an object array using a custom order |
Arrays.binarySearch(arr, key) |
Finds the index of key in a sorted array |
Arrays.fill(arr, value) |
Sets every element to value |
Arrays.copyOf(arr, newLength) |
Returns a new array, truncated or zero/null-padded |
Arrays.copyOfRange(arr, from, to) |
Returns a new array with elements [from, to) |
Arrays.equals(a, b) |
Compares two 1D arrays element by element |
Arrays.deepEquals(a, b) |
Compares nested (multi-dimensional) arrays recursively |
Arrays.toString(arr) |
Returns a readable [a, b, c] style string |
Arrays.deepToString(arr) |
Readable string for nested arrays |
Arrays.asList(arr) |
Wraps an array in a fixed-size List view |
Examples
Example 1: Sorting and printing
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
int[] numbers = {5, 3, 8, 1, 9, 2};
System.out.println("Original: " + Arrays.toString(numbers));
Arrays.sort(numbers);
System.out.println("Sorted: " + Arrays.toString(numbers));
}
}
Output:
Original: [5, 3, 8, 1, 9, 2]
Sorted: [1, 2, 3, 5, 8, 9]
Arrays.sort uses a dual-pivot quicksort for primitive arrays (fast, in-place, but not stable) and a stable, adaptive merge sort (TimSort) for object arrays, because sorting objects sometimes needs to preserve the original relative order of equal elements. Arrays.toString is what you should always use to print array contents—printing the array variable directly does not work as you’d expect (see Common Mistakes below).
Example 2: Searching, filling, and copying
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
int[] scores = {40, 55, 60, 75, 90};
int index = Arrays.binarySearch(scores, 60);
System.out.println("Index of 60: " + index);
int[] filled = new int[5];
Arrays.fill(filled, 7);
System.out.println("Filled: " + Arrays.toString(filled));
int[] extended = Arrays.copyOf(scores, 7);
System.out.println("Copied with extra: " + Arrays.toString(extended));
int[] range = Arrays.copyOfRange(scores, 1, 4);
System.out.println("Range [1,4): " + Arrays.toString(range));
}
}
Output:
Index of 60: 2
Filled: [7, 7, 7, 7, 7]
Copied with extra: [40, 55, 60, 75, 90, 0, 0]
Range [1,4): [55, 60, 75]
binarySearch requires a sorted array—scores already was, so it correctly finds 60 at index 2. copyOf to a larger length pads the new slots with the default value (0 for int, null for objects). copyOfRange follows the same half-open convention as String.substring: the end index is exclusive.
Example 3: Custom sort order and multi-dimensional arrays
import java.util.Arrays;
import java.util.Comparator;
public class Main {
public static void main(String[] args) {
String[] names = {"Charlie", "Alice", "Bob"};
Arrays.sort(names);
System.out.println("Alphabetical: " + Arrays.toString(names));
Arrays.sort(names, Comparator.reverseOrder());
System.out.println("Reverse: " + Arrays.toString(names));
int[][] grid = {{1, 2}, {3, 4}};
int[][] gridCopy = {{1, 2}, {3, 4}};
System.out.println("equals: " + Arrays.equals(grid, gridCopy));
System.out.println("deepEquals: " + Arrays.deepEquals(grid, gridCopy));
System.out.println("deepToString: " + Arrays.deepToString(grid));
}
}
Output:
Alphabetical: [Alice, Bob, Charlie]
Reverse: [Charlie, Bob, Alice]
equals: false
deepEquals: true
deepToString: [[1, 2], [3, 4]]
Note that Arrays.equals returns false for the two grids: a 2D array in Java is really an array of array references, so equals only compares those references (which point to different inner arrays), not their contents. deepEquals recurses into nested arrays and compares actual values, and deepToString is the only way to print a 2D array’s contents correctly.
How it works step by step (under the hood)
- Primitive sort: for
int[],double[], etc.,Arrays.sortruns a dual-pivot quicksort variant directly over the array’s memory, swapping elements in place with O(n log n) average time and O(1) extra space. - Object sort: for
Object[](includingString[]),Arrays.sortuses a stable merge sort (TimSort), which needs O(n) auxiliary space but guarantees elements considered “equal” by the comparator keep their original relative order. - binarySearch: repeatedly halves the search range, comparing the middle element to the key. This only works correctly if the array is already sorted in ascending order—the algorithm has no way to detect an unsorted array and will silently return a wrong or misleading result.
- copyOf / copyOfRange: internally call
System.arraycopy, a native method that performs a fast, low-level memory copy rather than a Java loop, which is why these methods are much faster than manually copying elements one by one. - asList: wraps the existing array in a
Listobject without copying data; the returned list is backed directly by the array, so changes to one are visible through the other.
Common Mistakes
Mistake 1: Printing an array directly instead of using Arrays.toString
Arrays do not override toString(), so printing one directly prints its type and memory-derived hash code, not its contents.
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
int[] data = {10, 20, 30};
System.out.println(data);
}
}
Output (exact hash varies each run):
[I@1540e19d
The fix is to always wrap the array with Arrays.toString (or Arrays.deepToString for nested arrays):
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
int[] data = {10, 20, 30};
System.out.println(Arrays.toString(data));
}
}
Output:
[10, 20, 30]
Mistake 2: Trying to add or remove elements from Arrays.asList
Arrays.asList returns a fixed-size List view backed by the array. Structural changes like add or remove are not supported because that would require resizing the underlying array.
import java.util.Arrays;
import java.util.List;
public class Main {
public static void main(String[] args) {
Integer[] nums = {1, 2, 3};
List list = Arrays.asList(nums);
try {
list.add(4);
} catch (UnsupportedOperationException e) {
System.out.println("Error: " + e);
}
}
}
Output:
Error: java.lang.UnsupportedOperationException
If you need a resizable list from an array, copy the fixed-size view into a real ArrayList:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class Main {
public static void main(String[] args) {
Integer[] nums = {1, 2, 3};
List list = new ArrayList<>(Arrays.asList(nums));
list.add(4);
System.out.println(list);
}
}
Output:
[1, 2, 3, 4]
A related pitfall: calling Arrays.binarySearch on an unsorted array does not throw an error—it just returns an unreliable index, because the algorithm assumes sorted input without checking. Always Arrays.sort first.
Best Practices
- Always use
Arrays.toStringorArrays.deepToStringto display array contents; never print the array reference directly. - Sort with
Arrays.sortbefore callingArrays.binarySearch—the search silently gives wrong answers on unsorted input. - Use
Arrays.equalsfor 1D arrays andArrays.deepEqualsfor multi-dimensional or nested arrays; never rely on==, which only compares references. - Prefer
Arrays.copyOf/copyOfRangeover manual copy loops—they are implemented with fast native memory copies. - Remember
Arrays.asListis backed by the original array and is fixed-size; wrap it innew ArrayList<>(...)if you need to add or remove elements. - For object arrays, pass a
ComparatortoArrays.sortwhen you need a non-natural order (descending, by field, etc.).
Practice Exercises
- Exercise 1: Given
int[] temps = {72, 68, 90, 61, 85};, write a program that prints the array, sorts it, then usesArrays.binarySearchto find the index of85after sorting. - Exercise 2: Create a
String[]of five fruit names in random order. Sort them alphabetically and print the result, then sort them by length using a customComparatorand print that result too. - Exercise 3: Create two 2D
intarrays with identical contents but built separately (not the same reference). UseArrays.equalsandArrays.deepEqualson them and print both results, explaining in a comment why they differ.
Summary
java.util.Arraysis a final utility class of static methods for working with arrays—it can never be instantiated.sortandfillmutate the array in place;copyOfandcopyOfRangereturn brand-new arrays.binarySearchonly works correctly on a sorted array.- Use
toString/deepToStringto print arrays, andequals/deepEqualsto compare them—never print or compare an array directly. asListgives a fixed-size, array-backedListview; wrap it in anArrayListfor a resizable list.
