5.4 Arrays Utility Class
Java provides the java.util.Arrays class so that developers can easily handle printing, copying, sorting, and searching arrays without manually writing loops every time. All methods in this class are static, so they can be called without creating an object.
1. Printing Arrays: Arrays.toString() / Arrays.deepToString()
Printing an array directly with println() gives a meaningless memory address.
import java.util.Arrays;
int[] arr = {10, 20, 30, 40, 50};
System.out.println(arr); // [I@7ef88735 (address, meaningless)
System.out.println(Arrays.toString(arr)); // [10, 20, 30, 40, 50]
2D Arrays: deepToString()
int[][] matrix = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
System.out.println(Arrays.toString(matrix)); // [[I@..., [I@..., ...] (wrong)
System.out.println(Arrays.deepToString(matrix)); // [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
2. Sorting Arrays: Arrays.sort()
Sorts array elements in ascending order. Internally uses the Dual-Pivot Quicksort algorithm.
Default Sort (Ascending)
int[] numbers = {5, 3, 8, 1, 9, 2, 7, 4, 6};
Arrays.sort(numbers);
System.out.println(Arrays.toString(numbers));
// [1, 2, 3, 4, 5, 6, 7, 8, 9]
String[] names = {"Charlie", "Alice", "Bob", "David"};
Arrays.sort(names);
System.out.println(Arrays.toString(names));
// [Alice, Bob, Charlie, David]
Partial Sort
int[] arr = {5, 3, 8, 1, 9, 2, 7};
Arrays.sort(arr, 1, 5); // sort only indices 1 to 4 (exclusive of 5)
System.out.println(Arrays.toString(arr));
// [5, 1, 3, 8, 9, 2, 7] - only indices 1 to 4 are sorted
Descending Sort (Using Comparator)
Primitive arrays cannot use Comparator directly, so convert to Integer[], or use IntStream in Java 8+.
// Using Integer[] (boxing)
Integer[] nums = {5, 3, 8, 1, 9};
Arrays.sort(nums, Comparator.reverseOrder()); // descending
System.out.println(Arrays.toString(nums)); // [9, 8, 5, 3, 1]
// Descending sort for String array
String[] words = {"banana", "apple", "cherry"};
Arrays.sort(words, Comparator.reverseOrder());
System.out.println(Arrays.toString(words)); // [cherry, banana, apple]
// Sort by length
Arrays.sort(words, Comparator.comparingInt(String::length));
System.out.println(Arrays.toString(words)); // [apple, banana, cherry]
3. Binary Search: Arrays.binarySearch()
Searches for a specific value in a sorted array in O(log n) time.
binarySearch() only returns accurate results when the array is sorted in ascending order.
int[] sorted = {10, 20, 30, 40, 50, 60, 70};
Arrays.sort(sorted); // already sorted, but check as a habit
int idx = Arrays.binarySearch(sorted, 40);
System.out.println("Position of 40: " + idx); // 3
int notFound = Arrays.binarySearch(sorted, 35);
System.out.println("Position of 35: " + notFound); // negative (not found)
Return values:
- If the value exists: its index (0 or greater)
- If not found:
-(insertion point) - 1(negative)
// Also works with String arrays
String[] names = {"Alice", "Bob", "Charlie", "David", "Eve"};
Arrays.sort(names);
int pos = Arrays.binarySearch(names, "Charlie");
System.out.println("Position of Charlie: " + pos); // 2
int notFound = Arrays.binarySearch(names, "Frank");
System.out.println("Position of Frank: " + notFound); // negative (-6)
4. Filling Arrays: Arrays.fill()
Fills all elements (or a range) of an array with a specific value.
int[] arr = new int[5];
// Fill all
Arrays.fill(arr, 7);
System.out.println(Arrays.toString(arr)); // [7, 7, 7, 7, 7]
// Fill a range (indices 1 to 3)
Arrays.fill(arr, 1, 4, 99);
System.out.println(Arrays.toString(arr)); // [7, 99, 99, 99, 7]
// Use for initialization
int[] board = new int[10];
Arrays.fill(board, -1); // initialize to -1 (e.g., to mark unvisited)
System.out.println(Arrays.toString(board)); // [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1]
5. Copying Arrays: Arrays.copyOf() / Arrays.copyOfRange()
int[] original = {1, 2, 3, 4, 5};
// Copy with the same size
int[] copy1 = Arrays.copyOf(original, original.length);
System.out.println(Arrays.toString(copy1)); // [1, 2, 3, 4, 5]
// Copy to a larger array (remaining elements are 0)
int[] copy2 = Arrays.copyOf(original, 8);
System.out.println(Arrays.toString(copy2)); // [1, 2, 3, 4, 5, 0, 0, 0]
// Copy to a smaller array (truncated)
int[] copy3 = Arrays.copyOf(original, 3);
System.out.println(Arrays.toString(copy3)); // [1, 2, 3]
// Copy a range (index 1 inclusive to 4 exclusive)
int[] copy4 = Arrays.copyOfRange(original, 1, 4);
System.out.println(Arrays.toString(copy4)); // [2, 3, 4]
// If the range exceeds the array length, filled with 0
int[] copy5 = Arrays.copyOfRange(original, 3, 8);
System.out.println(Arrays.toString(copy5)); // [4, 5, 0, 0, 0]
6. Comparing Arrays: Arrays.equals() / Arrays.deepEquals()
int[] a = {1, 2, 3};
int[] b = {1, 2, 3};
int[] c = {1, 2, 4};
System.out.println(a == b); // false (different objects)
System.out.println(Arrays.equals(a, b)); // true (same content)
System.out.println(Arrays.equals(a, c)); // false (different content)
// Comparing 2D arrays
int[][] m1 = {{1, 2}, {3, 4}};
int[][] m2 = {{1, 2}, {3, 4}};
System.out.println(Arrays.equals(m1, m2)); // false (shallow comparison)
System.out.println(Arrays.deepEquals(m1, m2)); // true (deep comparison)
7. Converting Array to List: Arrays.asList()
Converting an array to a List allows you to use the Collections API.
import java.util.Arrays;
import java.util.List;
import java.util.ArrayList;
String[] arr = {"Apple", "Banana", "Orange"};
// Fixed-size List (cannot add/remove!)
List<String> fixedList = Arrays.asList(arr);
System.out.println(fixedList); // [Apple, Banana, Orange]
// fixedList.add("Grape"); // UnsupportedOperationException!
// Copy to a new ArrayList to make it modifiable
List<String> mutableList = new ArrayList<>(Arrays.asList(arr));
mutableList.add("Grape");
System.out.println(mutableList); // [Apple, Banana, Orange, Grape]
The List returned by Arrays.asList() is fixed in size. set() (changing a value) is allowed, but add() and remove() are not. Also, a primitive array (int[]) becomes List<int[]>, so use Integer[] instead.
int[] primitives = {1, 2, 3};
List<int[]> wrong = Arrays.asList(primitives); // the List has one element: the int[] array!
Integer[] boxed = {1, 2, 3};
List<Integer> correct = Arrays.asList(boxed); // [1, 2, 3]
8. Converting Array to Stream: Arrays.stream()
In Java 8+, arrays can be converted to streams for functional-style processing.
import java.util.Arrays;
int[] numbers = {3, 1, 4, 1, 5, 9, 2, 6};
// Sum
int sum = Arrays.stream(numbers).sum();
System.out.println("Sum: " + sum); // 31
// Max/Min
int max = Arrays.stream(numbers).max().getAsInt();
int min = Arrays.stream(numbers).min().getAsInt();
System.out.println("Max: " + max + ", Min: " + min); // Max: 9, Min: 1
// Average
double avg = Arrays.stream(numbers).average().getAsDouble();
System.out.println("Average: " + avg); // 3.875
// Filter and convert back to array
int[] evens = Arrays.stream(numbers).filter(n -> n % 2 == 0).toArray();
System.out.println("Evens only: " + Arrays.toString(evens)); // [4, 2, 6]
// Transform each element (double)
int[] doubled = Arrays.stream(numbers).map(n -> n * 2).toArray();
System.out.println("Doubled: " + Arrays.toString(doubled)); // [6, 2, 8, 2, 10, 18, 4, 12]
9. Brief Introduction to the Collections Utility Class
java.util.Collections is a utility class for Lists. Convert an array to a List first to use it.
import java.util.Arrays;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
List<Integer> list = new ArrayList<>(Arrays.asList(5, 3, 8, 1, 9, 2));
// Sort
Collections.sort(list);
System.out.println(list); // [1, 2, 3, 5, 8, 9]
// Max/Min
System.out.println(Collections.max(list)); // 9
System.out.println(Collections.min(list)); // 1
// Shuffle randomly
Collections.shuffle(list);
System.out.println(list); // random order
// Reverse
Collections.reverse(list);
System.out.println(list); // reversed from current order
// Frequency count
List<String> words = Arrays.asList("apple", "banana", "apple", "cherry", "apple");
System.out.println(Collections.frequency(words, "apple")); // 3
10. Practical Example: Sort a Student Name Array and Binary Search
import java.util.Arrays;
import java.util.Scanner;
public class StudentSearch {
public static void main(String[] args) {
String[] students = {
"Hong", "Kim", "Lee", "Park", "Choi",
"Jung", "Kang", "Yoon", "Lim", "Oh"
};
System.out.println("Original list:");
System.out.println(Arrays.toString(students));
// Ascending sort
Arrays.sort(students);
System.out.println("\nSorted list:");
System.out.println(Arrays.toString(students));
// Search by binary search
Scanner scanner = new Scanner(System.in);
System.out.print("\nEnter student name to search: ");
String target = scanner.next();
int index = Arrays.binarySearch(students, target);
if (index >= 0) {
System.out.println(target + " is at position " + (index + 1) + ".");
} else {
System.out.println(target + " is not in the list.");
// Calculate insertion point: -(index + 1)
int insertPos = -(index + 1);
System.out.println("To add, insert at position " + (insertPos + 1) + ".");
}
// Additional statistics
System.out.println("\nName length statistics:");
int totalLen = 0;
for (String s : students) totalLen += s.length();
System.out.printf("Average name length: %.1f characters%n", (double) totalLen / students.length);
int longestIdx = 0;
for (int i = 1; i < students.length; i++) {
if (students[i].length() > students[longestIdx].length()) {
longestIdx = i;
}
}
System.out.println("Longest name: " + students[longestIdx]);
scanner.close();
}
}
Sample run:
Original list:
[Hong, Kim, Lee, Park, Choi, Jung, Kang, Yoon, Lim, Oh]
Sorted list:
[Choi, Hong, Jung, Kang, Kim, Lee, Lim, Oh, Park, Yoon]
Enter student name to search: Lee
Lee is at position 6.
11. Arrays Method Quick Reference
| Method | Description | Example |
|---|---|---|
toString(arr) | Converts 1D array to string | [1, 2, 3] |
deepToString(arr) | Converts multi-dimensional array to string | [[1, 2], [3, 4]] |
sort(arr) | Ascending sort | - |
sort(arr, from, to) | Partial sort | - |
sort(arr, comparator) | Custom sort | - |
binarySearch(arr, key) | Binary search | index or negative |
fill(arr, val) | Fill all elements | - |
fill(arr, from, to, val) | Fill a range | - |
copyOf(arr, len) | Copy with specified length | - |
copyOfRange(arr, from, to) | Copy a range | - |
equals(a, b) | Compare 1D arrays | true/false |
deepEquals(a, b) | Compare multi-dimensional arrays | true/false |
asList(arr) | Array to fixed List | - |
stream(arr) | Array to Stream | - |
Arrays Usage Patterns in Production:
- Debugging: Quickly inspect array contents with
System.out.println(Arrays.toString(arr)) - Expanding arrays: Double the array size with
Arrays.copyOf(arr, arr.length * 2) - Defensive copy: Protect the original when returning an array from a method with
return arr.clone() - Replacing equals: Verify arrays in unit tests with
Arrays.equals(expected, actual)
// Defensive copy example
public class SafeArray {
private int[] data;
public SafeArray(int[] input) {
this.data = input.clone(); // defend against external array modification
}
public int[] getData() {
return data.clone(); // defend against exposing internal array
}
}