Complete guide to array operations in Java covering searching, sorting, insertion, deletion, merging, rotation, reversing, and all java.util.Arrays class methods with detailed examples.
Overview
Array operations are the fundamental actions you perform on arrays — searching for elements, sorting them, inserting/deleting values, copying, merging, and transforming. Mastering these operations is essential because they form the foundation of all data structure algorithms.
This chapter covers:
- Traversal — visiting every element
- Searching — finding elements (Linear & Binary Search)
- Sorting — arranging elements (Bubble, Selection, Insertion Sort)
- Insertion — adding elements at a position
- Deletion — removing elements from a position
- Merging — combining two arrays
- Rotation — shifting elements left or right
- Reversing — flipping the array
- java.util.Arrays class — built-in utility methods
1. Traversal
Traversal means visiting every element exactly once to perform an operation (print, sum, count, etc.).
public class ArrayTraversal {
public static void main(String[] args) {
int[] arr = {10, 25, 30, 45, 50, 65, 70};
// Operation 1: Sum of all elements
int sum = 0;
for (int val : arr) {
sum += val;
}
System.out.println("Sum: " + sum);
// Operation 2: Count elements greater than 40
int count = 0;
for (int val : arr) {
if (val > 40) count++;
}
System.out.println("Elements > 40: " + count);
// Operation 3: Find min and max
int min = arr[0], max = arr[0];
for (int i = 1; i < arr.length; i++) {
if (arr[i] < min) min = arr[i];
if (arr[i] > max) max = arr[i];
}
System.out.println("Min: " + min + ", Max: " + max);
}
}
Sum: 295
Elements > 40: 4
Min: 10, Max: 70
Time Complexity: O(n) — must visit every element once.
2. Searching
Linear Search
Linear search checks every element sequentially until the target is found or the array ends.
public class LinearSearch {
public static int linearSearch(int[] arr, int key) {
for (int i = 0; i < arr.length; i++) {
if (arr[i] == key) {
return i; // Found at index i
}
}
return -1; // Not found
}
public static void main(String[] args) {
int[] arr = {23, 56, 12, 78, 45, 90, 34};
int key1 = 78;
int result1 = linearSearch(arr, key1);
System.out.println(key1 + " found at index: " + result1);
int key2 = 99;
int result2 = linearSearch(arr, key2);
System.out.println(key2 + " found at index: " + result2);
}
}
78 found at index: 3
99 found at index: -1
Time Complexity: O(n) worst case, O(1) best case Space Complexity: O(1) Works on: Sorted and unsorted arrays
Binary Search
Binary search works only on sorted arrays. It repeatedly divides the search space in half.
public class BinarySearch {
public static int binarySearch(int[] arr, int key) {
int low = 0, high = arr.length - 1;
while (low <= high) {
int mid = low + (high - low) / 2; // Prevents overflow
if (arr[mid] == key) {
return mid; // Found!
} else if (arr[mid] < key) {
low = mid + 1; // Search right half
} else {
high = mid - 1; // Search left half
}
}
return -1; // Not found
}
public static void main(String[] args) {
int[] sorted = {10, 20, 30, 40, 50, 60, 70, 80, 90, 100};
System.out.println("Searching for 60:");
int result = binarySearch(sorted, 60);
System.out.println("Found at index: " + result);
System.out.println("\nSearching for 55:");
result = binarySearch(sorted, 55);
System.out.println("Found at index: " + result);
}
}
Searching for 60:
Found at index: 5
Searching for 55:
Found at index: -1
Dry Run for key = 60:
| Initial | low=0, high=9 |
| Step 1: mid=4, arr[4]=50 < 60 | low=5 |
| Step 2: mid=7, arr[7]=80 > 60 | high=6 |
| Step 3: mid=5, arr[5]=60 == 60 | FOUND at index 5 |
Time Complexity: O(log n) Space Complexity: O(1) iterative, O(log n) recursive Prerequisite: Array must be sorted
3. Sorting
Bubble Sort
Repeatedly swaps adjacent elements if they are in the wrong order. After each pass, the largest unsorted element "bubbles" to its correct position.
import java.util.Arrays;
public class BubbleSort {
public static void bubbleSort(int[] arr) {
int n = arr.length;
boolean swapped;
for (int i = 0; i < n - 1; i++) {
swapped = false;
for (int j = 0; j < n - 1 - i; j++) {
if (arr[j] > arr[j + 1]) {
// Swap
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
swapped = true;
}
}
if (!swapped) break; // Optimization: already sorted
System.out.println("After pass " + (i+1) + ": " + Arrays.toString(arr));
}
}
public static void main(String[] args) {
int[] arr = {64, 34, 25, 12, 22, 11, 90};
System.out.println("Original: " + Arrays.toString(arr));
bubbleSort(arr);
System.out.println("Sorted: " + Arrays.toString(arr));
}
}
Original: [64, 34, 25, 12, 22, 11, 90]
After pass 1: [34, 25, 12, 22, 11, 64, 90]
After pass 2: [25, 12, 22, 11, 34, 64, 90]
After pass 3: [12, 22, 11, 25, 34, 64, 90]
After pass 4: [12, 11, 22, 25, 34, 64, 90]
After pass 5: [11, 12, 22, 25, 34, 64, 90]
Sorted: [11, 12, 22, 25, 34, 64, 90]
Time Complexity: O(n²) worst/average, O(n) best (already sorted with optimization)
Selection Sort
Finds the minimum element and places it at the beginning, then repeats for the remaining unsorted portion.
import java.util.Arrays;
public class SelectionSort {
public static void selectionSort(int[] arr) {
int n = arr.length;
for (int i = 0; i < n - 1; i++) {
int minIdx = i;
for (int j = i + 1; j < n; j++) {
if (arr[j] < arr[minIdx]) {
minIdx = j;
}
}
// Swap arr[i] and arr[minIdx]
int temp = arr[i];
arr[i] = arr[minIdx];
arr[minIdx] = temp;
System.out.println("After pass " + (i+1) + ": " + Arrays.toString(arr));
}
}
public static void main(String[] args) {
int[] arr = {64, 25, 12, 22, 11};
System.out.println("Original: " + Arrays.toString(arr));
selectionSort(arr);
System.out.println("Sorted: " + Arrays.toString(arr));
}
}
Original: [64, 25, 12, 22, 11]
After pass 1: [11, 25, 12, 22, 64]
After pass 2: [11, 12, 25, 22, 64]
After pass 3: [11, 12, 22, 25, 64]
After pass 4: [11, 12, 22, 25, 64]
Sorted: [11, 12, 22, 25, 64]
Time Complexity: O(n²) always (no best-case optimization) Advantage: Minimum number of swaps (at most n-1)
Insertion Sort
Builds the sorted array one element at a time by inserting each element into its correct position.
import java.util.Arrays;
public class InsertionSort {
public static void insertionSort(int[] arr) {
int n = arr.length;
for (int i = 1; i < n; i++) {
int key = arr[i];
int j = i - 1;
// Shift elements greater than key to the right
while (j >= 0 && arr[j] > key) {
arr[j + 1] = arr[j];
j--;
}
arr[j + 1] = key;
System.out.println("After inserting " + key + ": " + Arrays.toString(arr));
}
}
public static void main(String[] args) {
int[] arr = {12, 11, 13, 5, 6};
System.out.println("Original: " + Arrays.toString(arr));
insertionSort(arr);
System.out.println("Sorted: " + Arrays.toString(arr));
}
}
Original: [12, 11, 13, 5, 6]
After inserting 11: [11, 12, 13, 5, 6]
After inserting 13: [11, 12, 13, 5, 6]
After inserting 5: [5, 11, 12, 13, 6]
After inserting 6: [5, 6, 11, 12, 13]
Sorted: [5, 6, 11, 12, 13]
Time Complexity: O(n²) worst, O(n) best (already sorted) Best for: Small arrays or nearly sorted arrays
4. Insertion at a Position
Since arrays are fixed-size, insertion requires shifting elements to make room.
import java.util.Arrays;
public class ArrayInsertion {
public static int[] insertAt(int[] arr, int size, int pos, int value) {
// Shift elements to the right
for (int i = size - 1; i >= pos; i--) {
arr[i + 1] = arr[i];
}
arr[pos] = value;
return arr;
}
public static void main(String[] args) {
int[] arr = new int[10]; // Extra space for insertion
arr[0] = 10; arr[1] = 20; arr[2] = 30; arr[3] = 40; arr[4] = 50;
int size = 5;
System.out.println("Before: " + Arrays.toString(Arrays.copyOf(arr, size)));
insertAt(arr, size, 2, 25); // Insert 25 at index 2
size++;
System.out.println("After inserting 25 at index 2: " + Arrays.toString(Arrays.copyOf(arr, size)));
}
}
Before: [10, 20, 30, 40, 50]
After inserting 25 at index 2: [10, 20, 25, 30, 40, 50]
Time Complexity: O(n) — shifting elements
5. Deletion from a Position
Deletion requires shifting elements to the left to fill the gap.
import java.util.Arrays;
public class ArrayDeletion {
public static int deleteAt(int[] arr, int size, int pos) {
System.out.println("Deleting element " + arr[pos] + " at index " + pos);
// Shift elements to the left
for (int i = pos; i < size - 1; i++) {
arr[i] = arr[i + 1];
}
arr[size - 1] = 0; // Clear last position
return size - 1; // New size
}
public static void main(String[] args) {
int[] arr = {10, 20, 30, 40, 50, 60};
int size = 6;
System.out.println("Before: " + Arrays.toString(Arrays.copyOf(arr, size)));
size = deleteAt(arr, size, 2); // Delete element at index 2
System.out.println("After: " + Arrays.toString(Arrays.copyOf(arr, size)));
}
}
Before: [10, 20, 30, 40, 50, 60]
Deleting element 30 at index 2
After: [10, 20, 40, 50, 60]
Time Complexity: O(n) — shifting elements
6. Merging Two Arrays
Simple Concatenation
import java.util.Arrays;
public class ArrayMerge {
public static int[] merge(int[] arr1, int[] arr2) {
int[] result = new int[arr1.length + arr2.length];
System.arraycopy(arr1, 0, result, 0, arr1.length);
System.arraycopy(arr2, 0, result, arr1.length, arr2.length);
return result;
}
public static void main(String[] args) {
int[] a = {1, 3, 5, 7};
int[] b = {2, 4, 6, 8};
int[] merged = merge(a, b);
System.out.println("Array 1: " + Arrays.toString(a));
System.out.println("Array 2: " + Arrays.toString(b));
System.out.println("Merged: " + Arrays.toString(merged));
}
}
Array 1: [1, 3, 5, 7]
Array 2: [2, 4, 6, 8]
Merged: [1, 3, 5, 7, 2, 4, 6, 8]
Merge Two Sorted Arrays (Maintaining Sort Order)
import java.util.Arrays;
public class MergeSorted {
public static int[] mergeSorted(int[] a, int[] b) {
int[] result = new int[a.length + b.length];
int i = 0, j = 0, k = 0;
while (i < a.length && j < b.length) {
if (a[i] <= b[j]) {
result[k++] = a[i++];
} else {
result[k++] = b[j++];
}
}
// Copy remaining elements
while (i < a.length) result[k++] = a[i++];
while (j < b.length) result[k++] = b[j++];
return result;
}
public static void main(String[] args) {
int[] a = {1, 3, 5, 7, 9};
int[] b = {2, 4, 6, 8, 10, 12};
int[] merged = mergeSorted(a, b);
System.out.println("Merged sorted: " + Arrays.toString(merged));
}
}
Merged sorted: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12]
Time Complexity: O(n + m) where n and m are lengths of the two arrays
7. Array Rotation
Left Rotation by d Positions
import java.util.Arrays;
public class LeftRotation {
public static void rotateLeft(int[] arr, int d) {
int n = arr.length;
d = d % n; // Handle d > n
// Method: Using temporary array
int[] temp = new int[d];
// Store first d elements
System.arraycopy(arr, 0, temp, 0, d);
// Shift remaining elements left
System.arraycopy(arr, d, arr, 0, n - d);
// Put stored elements at the end
System.arraycopy(temp, 0, arr, n - d, d);
}
public static void main(String[] args) {
int[] arr = {1, 2, 3, 4, 5, 6, 7};
System.out.println("Original: " + Arrays.toString(arr));
rotateLeft(arr, 2);
System.out.println("Left rotate by 2: " + Arrays.toString(arr));
}
}
Original: [1, 2, 3, 4, 5, 6, 7]
Left rotate by 2: [3, 4, 5, 6, 7, 1, 2]
Right Rotation by d Positions
import java.util.Arrays;
public class RightRotation {
public static void rotateRight(int[] arr, int d) {
int n = arr.length;
d = d % n;
// Right rotation by d = Left rotation by (n - d)
int[] temp = new int[d];
// Store last d elements
System.arraycopy(arr, n - d, temp, 0, d);
// Shift remaining elements right
System.arraycopy(arr, 0, arr, d, n - d);
// Put stored elements at the beginning
System.arraycopy(temp, 0, arr, 0, d);
}
public static void main(String[] args) {
int[] arr = {1, 2, 3, 4, 5, 6, 7};
System.out.println("Original: " + Arrays.toString(arr));
rotateRight(arr, 3);
System.out.println("Right rotate by 3: " + Arrays.toString(arr));
}
}
Original: [1, 2, 3, 4, 5, 6, 7]
Right rotate by 3: [5, 6, 7, 1, 2, 3, 4]
8. Reversing an Array
import java.util.Arrays;
public class ArrayReverse {
public static void reverse(int[] arr) {
int left = 0, right = arr.length - 1;
while (left < right) {
int temp = arr[left];
arr[left] = arr[right];
arr[right] = temp;
left++;
right--;
}
}
public static void main(String[] args) {
int[] arr = {10, 20, 30, 40, 50};
System.out.println("Original: " + Arrays.toString(arr));
reverse(arr);
System.out.println("Reversed: " + Arrays.toString(arr));
}
}
Original: [10, 20, 30, 40, 50]
Reversed: [50, 40, 30, 20, 10]
Time Complexity: O(n/2) = O(n) Space Complexity: O(1)
9. java.util.Arrays Class — Complete Reference
The java.util.Arrays class provides static utility methods for arrays.
import java.util.Arrays;
public class ArraysClassDemo {
public static void main(String[] args) {
int[] arr = {45, 12, 78, 34, 56, 23, 89, 67};
// 1. toString() - readable string
System.out.println("1. toString: " + Arrays.toString(arr));
// 2. sort() - ascending order
int[] sortArr = arr.clone();
Arrays.sort(sortArr);
System.out.println("2. sort: " + Arrays.toString(sortArr));
// 3. sort range [fromIndex, toIndex)
int[] partialSort = arr.clone();
Arrays.sort(partialSort, 2, 6); // Sort indices 2-5
System.out.println("3. sort(2,6): " + Arrays.toString(partialSort));
// 4. binarySearch (array MUST be sorted)
int idx = Arrays.binarySearch(sortArr, 56);
System.out.println("4. binarySearch(56): index " + idx);
// 5. fill
int[] filled = new int[5];
Arrays.fill(filled, 42);
System.out.println("5. fill(42): " + Arrays.toString(filled));
// 6. equals
int[] a = {1, 2, 3};
int[] b = {1, 2, 3};
int[] c = {1, 2, 4};
System.out.println("6. equals(a,b): " + Arrays.equals(a, b));
System.out.println(" equals(a,c): " + Arrays.equals(a, c));
// 7. copyOf
int[] copy = Arrays.copyOf(arr, 5); // First 5 elements
System.out.println("7. copyOf(5): " + Arrays.toString(copy));
// 8. copyOfRange
int[] range = Arrays.copyOfRange(arr, 2, 5);
System.out.println("8. copyOfRange(2,5): " + Arrays.toString(range));
// 9. mismatch (Java 9+) - first index where arrays differ
int[] x = {1, 2, 3, 4, 5};
int[] y = {1, 2, 9, 4, 5};
System.out.println("9. mismatch: " + Arrays.mismatch(x, y));
}
}
1. toString: [45, 12, 78, 34, 56, 23, 89, 67]
2. sort: [12, 23, 34, 45, 56, 67, 78, 89]
3. sort(2,6): [45, 12, 23, 34, 56, 78, 89, 67]
4. binarySearch(56): 4
5. fill(42): [42, 42, 42, 42, 42]
6. equals(a,b): true
equals(a,c): false
7. copyOf(5): [45, 12, 78, 34, 56]
8. copyOfRange(2,5): [78, 34, 56]
9. mismatch: 2
Remove Duplicates from Sorted Array
import java.util.Arrays;
public class RemoveDuplicates {
public static int removeDuplicates(int[] arr) {
if (arr.length == 0) return 0;
int uniqueIndex = 0;
for (int i = 1; i < arr.length; i++) {
if (arr[i] != arr[uniqueIndex]) {
uniqueIndex++;
arr[uniqueIndex] = arr[i];
}
}
return uniqueIndex + 1; // New size
}
public static void main(String[] args) {
int[] arr = {1, 1, 2, 2, 2, 3, 4, 4, 5, 5, 5, 5};
System.out.println("Original: " + Arrays.toString(arr));
int newSize = removeDuplicates(arr);
System.out.println("After removing duplicates: " + Arrays.toString(Arrays.copyOf(arr, newSize)));
System.out.println("Unique count: " + newSize);
}
}
Original: [1, 1, 2, 2, 2, 3, 4, 4, 5, 5, 5, 5]
After removing duplicates: [1, 2, 3, 4, 5]
Unique count: 5
Common Mistakes
1. Binary Search on Unsorted Array
int[] arr = {5, 2, 8, 1, 9};
// Arrays.binarySearch(arr, 8); // WRONG — undefined behavior!
Arrays.sort(arr); // Sort first!
Arrays.binarySearch(arr, 8); // Now correct
2. Modifying Array During Enhanced For Loop
int[] arr = {1, 2, 3, 4, 5};
for (int val : arr) {
// val = val * 2; // This does NOT modify the array!
}
// Use regular for loop to modify elements
3. Forgetting Insertion Shifts Right
// When inserting at index 2, shift from the END to avoid overwriting
// WRONG: shift left to right (overwrites data)
// RIGHT: shift right to left
4. Not Handling Rotation Edge Cases
// Always do d = d % n to handle d > array length
// rotateLeft(arr, 10) when arr.length = 7 → effectively rotate by 3
5. Arrays.sort() Modifies Original
int[] original = {5, 3, 1, 4, 2};
Arrays.sort(original); // Original is now sorted — previous order lost!
// Clone first if you need to keep the original
Best Practices
- Use
Arrays.sort() for production code — it uses dual-pivot quicksort (O(n log n)) - Always sort before binary search — binary search requires sorted input
- Use
System.arraycopy() for bulk element copying — it's native and fast - Handle edge cases — empty arrays, single element, rotation by array length
- Prefer in-place operations when memory is limited
- Use
Arrays.copyOf() for resizing — cleaner than manual copy - Validate indices before insertion/deletion operations
- Consider time-space tradeoffs — rotation using temp array is O(n) time O(d) space
- Use modulo for rotation — handles cases where d > array length
- Choose the right search — linear for unsorted, binary for sorted
Interview Questions
Q1: What is the time complexity of Arrays.sort() in Java? For primitive arrays, it uses dual-pivot quicksort with O(n log n) average case. For object arrays, it uses TimSort (merge sort variant) which is O(n log n) worst case and stable.
Q2: What happens if you call binarySearch on an unsorted array? The result is undefined — it may return any index or -1. Always sort first.
Q3: How do you rotate an array in O(n) time and O(1) space? Use the reversal algorithm: reverse first d elements, reverse remaining elements, then reverse the entire array.
Q4: What is the difference between Arrays.copyOf() and clone()? Both create new arrays. copyOf() allows specifying a different length (truncate or pad). clone() always creates same-length copy.
Q5: How do you find duplicates in an array? Multiple approaches: sort first then check adjacent (O(n log n)), use HashSet (O(n) time, O(n) space), or for limited range use counting array.
Q6: What is the merge operation used in merge sort? Merging two sorted arrays into one sorted array in O(n+m) time using two pointers.
Q7: How do you find the intersection of two sorted arrays? Use two pointers: advance the pointer with the smaller element; when equal, add to result and advance both.
Q8: What is the difference between System.arraycopy() and Arrays.copyOf()? System.arraycopy() copies between existing arrays with source/dest offsets. Arrays.copyOf() creates a new array and copies elements.
Q9: Can Arrays.sort() sort in descending order for primitives? Not directly. Sort ascending then reverse, or use Integer[] with Arrays.sort(arr, Collections.reverseOrder()).
Q10: What is the time complexity of inserting/deleting in the middle of an array? O(n) because elements must be shifted. This is why LinkedList is preferred for frequent insertions/deletions.
Q11: What does Arrays.mismatch() return? Returns the index of the first difference between two arrays, or -1 if they are identical. Available since Java 9.
Q12: How does Arrays.fill() work? It assigns the same value to all elements (or a range) of an array. Time complexity is O(n).