Sorting
Arrays.sort() Methods
The Arrays class provides multiple sorting methods for arrays.
Natural Ordering
import java.util.Arrays;
// Primitive arrays - uses dual-pivot quicksort
int[] nums = {5, 2, 8, 1, 9};
Arrays.sort(nums); // [1, 2, 5, 8, 9]
// String arrays - lexicographic order
String[] fruits = {"banana", "apple", "cherry"};
Arrays.sort(fruits); // [apple, banana, cherry]
// Double arrays
double[] prices = {9.99, 4.99, 7.99};
Arrays.sort(prices); // [4.99, 7.99, 9.99]
Custom Ordering with Comparator
// Object arrays with custom Comparator
Integer[] nums = {5, 2, 8, 1, 9};
// Descending order
Arrays.sort(nums, Collections.reverseOrder()); // [9, 8, 5, 2, 1]
// Custom Comparator for Strings by length
String[] words = {"banana", "apple", "fig", "cherry"};
Arrays.sort(words, Comparator.comparingInt(String::length));
// [fig, apple, banana, cherry]
// Custom object sorting
class Student {
String name;
int grade;
Student(String name, int grade) {
this.name = name;
this.grade = grade;
}
}
Student[] students = {
new Student("Alice", 90),
new Student("Bob", 85),
new Student("Charlie", 95)
};
// Sort by grade descending
Arrays.sort(students, (a, b) -> b.grade - a.grade);
// Or using Comparator.comparingInt
Arrays.sort(students, Comparator.comparingInt((Student s) -> s.grade).reversed());
Partial Sort
int[] arr = {5, 2, 8, 1, 9, 3};
// Sort only from index 1 to 4
Arrays.sort(arr, 1, 5); // [5, 1, 2, 8, 9, 3]
// Elements at indices 1-4 are sorted
Stability
// Arrays.sort() for objects is stable
// Equal elements maintain their relative order
String[] arr = {"b1", "a1", "b2", "a2"};
Arrays.sort(arr, Comparator.comparing(s -> s.charAt(0)));
// Result: [a1, a2, b1, b2] - a1 before a2, b1 before b2
Search
Arrays.binarySearch()
Binary search requires a sorted array.
Basic Binary Search
import java.util.Arrays;
int[] arr = {1, 2, 3, 4, 5};
// Returns index if found, negative value if not found
int index = Arrays.binarySearch(arr, 3); // 2 (found)
int index2 = Arrays.binarySearch(arr, 6); // -6 (not found)
// Insertion point is: -(insertion point) - 1
// For value 6: insertion point would be 5
// Return value: -(5) - 1 = -6
Binary Search with Comparator
// For custom objects
String[] words = {"apple", "banana", "cherry"};
int index = Arrays.binarySearch(words, "banana"); // 1
// With custom Comparator
Integer[] nums = {5, 2, 8, 1, 9};
Arrays.sort(nums, Collections.reverseOrder()); // [9, 8, 5, 2, 1]
int index = Arrays.binarySearch(nums, 5, Collections.reverseOrder()); // 2
Range Binary Search
int[] arr = {1, 2, 3, 4, 5, 6, 7, 8, 9};
// Search only in range [2, 7)
int index = Arrays.binarySearch(arr, 2, 7, 5); // index of 5
Important Notes
// 1. Array MUST be sorted before binary search
int[] unsorted = {3, 1, 4, 1, 5};
Arrays.sort(unsorted); // Sort first!
int index = Arrays.binarySearch(unsorted, 4); // Now works
// 2. For duplicates, which index is returned is unspecified
int[] arr = {1, 2, 2, 2, 3};
int index = Arrays.binarySearch(arr, 2); // Could be 1, 2, or 3
// 3. Return value interpretation
// If found: index of element
// If not found: -(insertion point) - 1
// Insertion point: where element would be inserted to maintain order
Copy
Array Copying Methods
Arrays.copyOf()
import java.util.Arrays;
int[] src = {1, 2, 3, 4, 5};
// Copy with new length
int[] copy1 = Arrays.copyOf(src, 3); // [1, 2, 3]
int[] copy2 = Arrays.copyOf(src, 7); // [1, 2, 3, 4, 5, 0, 0]
// If new length > source, remaining elements are filled with defaults
int[] copy3 = Arrays.copyOf(src, src.length); // [1, 2, 3, 4, 5]
Arrays.copyOfRange()
int[] src = {1, 2, 3, 4, 5, 6, 7};
// Copy range [fromIndex, toIndex)
int[] range1 = Arrays.copyOfRange(src, 1, 4); // [2, 3, 4]
int[] range2 = Arrays.copyOfRange(src, 0, src.length); // [1, 2, 3, 4, 5, 6, 7]
// toIndex can be > length (no error)
int[] range3 = Arrays.copyOfRange(src, 3, 10); // [4, 5, 6, 7]
System.arraycopy()
int[] src = {1, 2, 3, 4, 5};
int[] dest = new int[7];
// System.arraycopy(src, srcPos, dest, destPos, length)
System.arraycopy(src, 1, dest, 2, 3);
// dest is now [0, 0, 2, 3, 4, 0, 0]
// Parameters:
// src: source array
// srcPos: starting position in source
// dest: destination array
// destPos: starting position in destination
// length: number of elements to copy
clone()
int[] src = {1, 2, 3, 4, 5};
int[] cloned = src.clone(); // [1, 2, 3, 4, 5]
// clone() creates shallow copy
// For primitive arrays, this is fine
// For object arrays, references are copied (not deep copy)
Comparison
// All methods create new array
int[] src = {1, 2, 3};
int[] a = Arrays.copyOf(src, 3);
int[] b = src.clone();
int[] c = new int[3];
System.arraycopy(src, 0, c, 0, 3);
// All produce same result, different syntax
// Use Arrays.copyOf for simplicity
// Use System.arraycopy for performance (native method)
Fill
Arrays.fill() Methods
Fill Entire Array
import java.util.Arrays;
int[] arr = new int[5];
Arrays.fill(arr, 10); // [10, 10, 10, 10, 10]
String[] words = new String[3];
Arrays.fill(words, "hello"); // [hello, hello, hello]
// Fill with different types
boolean[] flags = new boolean[4];
Arrays.fill(flags, true); // [true, true, true, true]
Fill Range
int[] arr = new int[7];
// Fill indices 2 to 5 with value 100
Arrays.fill(arr, 2, 6, 100);
// arr is now [0, 0, 100, 100, 100, 100, 0]
// Parameters: fill(array, fromIndex, toIndex, value)
// Range is [fromIndex, toIndex)
Practical Uses
// Initialize with default values
int[] arr = new int[10];
Arrays.fill(arr, -1); // All elements become -1
// Reset array
String[] cache = new String[100];
Arrays.fill(cache, null); // Clear all entries
// Create pattern
int[] arr = new int[10];
for (int i = 0; i < arr.length; i += 2) {
arr[i] = 1; // Set even indices to 1
}
// [1, 0, 1, 0, 1, 0, 1, 0, 1, 0]
Limitations
// Cannot fill with computed values
int[] arr = new int[5];
// Arrays.fill(arr, i -> i * 2); // DOES NOT EXIST
// Must use loop for computed values
for (int i = 0; i < arr.length; i++) {
arr[i] = i * 2;
}
Compare
Array Comparison Methods
Arrays.equals()
import java.util.Arrays;
int[] a = {1, 2, 3};
int[] b = {1, 2, 3};
int[] c = {1, 2, 4};
Arrays.equals(a, b); // true
Arrays.equals(a, c); // false
// Checks if arrays have same length and elements
// Does NOT check reference equality
Arrays.deepEquals()
// For multi-dimensional arrays
int[][] x = {{1, 2}, {3, 4}};
int[][] y = {{1, 2}, {3, 4}};
Arrays.equals(x, y); // false (compares references)
Arrays.deepEquals(x, y); // true (compares contents recursively)
// deepEquals works for any nesting depth
int[][][] a3d = {{{1, 2}, {3, 4}}, {{5, 6}, {7, 8}}};
int[][][] b3d = {{{1, 2}, {3, 4}}, {{5, 6}, {7, 8}}};
Arrays.deepEquals(a3d, b3d); // true
Arrays.deepHashCode()
int[][] x = {{1, 2}, {3, 4}};
int[][] y = {{1, 2}, {3, 4}};
Arrays.hashCode(x); // Some hash code
Arrays.deepHashCode(x); // Same hash code for equal deep structures
// Use deepHashCode for multi-dimensional arrays
Arrays.toString()
int[] arr = {1, 2, 3, 4, 5};
String str = Arrays.toString(arr); // "[1, 2, 3, 4, 5]"
// For multi-dimensional
int[][] arr2 = {{1, 2}, {3, 4}};
String str2 = Arrays.deepToString(arr2); // "[[1, 2], [3, 4]]"
// Useful for debugging
System.out.println(Arrays.toString(arr));
Sorting and Comparing
// To compare arrays regardless of order
int[] a = {1, 2, 3};
int[] b = {3, 1, 2};
int[] aSorted = a.clone();
int[] bSorted = b.clone();
Arrays.sort(aSorted);
Arrays.sort(bSorted);
boolean sameElements = Arrays.equals(aSorted, bSorted); // true
Practice Problems
Given an array of integers nums, sort the array in ascending order.
Example:
Input: nums = [5, 2, 3, 1]
Output: [1, 2, 3, 5]
Sort in ascending order
Optimal Solution — O(n log n) time, O(log n) space
Use Arrays.sort() which uses dual-pivot quicksort for primitives.
public int[] sortArray(int[] nums) {
Arrays.sort(nums);
return nums;
}Edge Cases:
- Empty array
- Single element
- Already sorted
Find the kth largest element in an unsorted array.
Example:
Input: nums = [3, 2, 1, 5, 6, 4], k = 2
Output: 5
The 2nd largest element is 5
Optimal Solution — O(n log n) time, O(1) space
Sort array and return the kth from end.
public int findKthLargest(int[] nums, int k) {
Arrays.sort(nums);
return nums[nums.length - k];
}Edge Cases:
- k = 1
- k = nums.length
- All same elements
Quiz
1. What must be true before using Arrays.binarySearch()?
2. What does Arrays.binarySearch() return if element is not found?
3. What is the difference between equals() and deepEquals()?
4. What is the primary purpose of Arrays Utility Class?
Flashcards
Question
How do you sort an array in descending order?
Click to reveal answer
Answer
Use Arrays.sort() with Collections.reverseOrder() as second argument, or sort then reverse.
Question
What is the difference between Arrays.copyOf() and System.arraycopy()?
Click to reveal answer
Answer
copyOf creates new array and copies, System.arraycopy copies into existing array. System.arraycopy is faster (native method).
Question
How do you fill an array with a value?
Click to reveal answer
Answer
Use Arrays.fill(array, value) for entire array, or Arrays.fill(array, fromIndex, toIndex, value) for a range.
Question
What is Arrays Utility Class?
Click to reveal answer
Answer
Arrays Utility Class is a key concept in Java programming.
Question
When to use Arrays Utility Class?
Click to reveal answer
Answer
Use Arrays Utility Class when building production systems that require reliability, scalability, and maintainability.
Revision Notes
Key Takeaways
- 1.Arrays.sort() uses dual-pivot quicksort for primitives (O(n log n))
- 2.Binary search requires sorted array
- 3.Use deepEquals for multi-dimensional arrays
- 4.Arrays are utility methods, not instance methods
Interview Tips
- •Know the time complexity of Arrays.sort()
- •Remember binary search returns -(insertion point) - 1 when not found
- •Use Comparator for custom sorting
- •Prefer Arrays.copyOf over manual loops for copying
Cheat Sheet
Cheat Sheet
- Sort:
Arrays.sort(arr)orArrays.sort(arr, comparator) - Search:
Arrays.binarySearch(arr, key) - Copy:
Arrays.copyOf(arr, len)orArrays.copyOfRange(arr, from, to) - Fill:
Arrays.fill(arr, val) - Compare:
Arrays.equals(a, b)orArrays.deepEquals(a, b) - Print:
Arrays.toString(arr)orArrays.deepToString(arr)