1D Arrays & Operations
Declaration, instantiation, comprehensive printing methods, static algorithm utilities, in-place manipulation, and LeetCode patterns
A one-dimensional (1D) array is a fixed-size, zero-indexed sequence of elements allocated contiguously in memory. Unlike dynamic collections, 1D arrays are low-level Java language constructs that can store primitive types with zero boxing overhead or object reference pointers.
Declaration & Instantiation
Java provides three primary syntax forms for creating 1D arrays:
// 1. Declaration + Allocation with default zero values (Heap allocated)
int[] nums = new int[5]; // length = 5, all elements = 0
// 2. Array Literal (compiler allocates and initializes values immediately)
int[] primes = {2, 3, 5, 7, 11}; // length = 5
// 3. Explicit Anonymous Array (useful when passing inline to methods or returning)
int[] scores = new int[]{98, 85, 92};
printScores(new int[]{100, 95, 90}); // pass inline without declaring a variableJava Style vs C-Style Declaration: Always place brackets next to the data type (int[] arr)
rather than the variable name (int arr[]). Placing brackets on the type avoids subtle
multi-variable declaration bugs: java int[] a, b; // Both a and b are int[] (Java style - Recommended) int a[], b; // a is int[], but b is a plain primitive int! (C-style trap)
Default Initialization Values
When an array is allocated using the new keyword, the JVM automatically initializes all memory slots to type-specific default values:
| Element Type | Default Value | Code Example |
|---|---|---|
byte, short, int, long | 0 | int[] arr = new int[3]; // [0, 0, 0] |
float, double | 0.0 | double[] arr = new double[2]; // [0.0, 0.0] |
boolean | false | boolean[] visited = new boolean[3]; // [false, false, false] |
char | '\u0000' (null char) | Prints as empty whitespace or NUL |
Any Object Reference (String, Integer, Node) | null | String[] words = new String[2]; // [null, null] |
Array Length: Field, Not a Method
In Java, arrays expose length as a public final field (arr.length), not a method (arr.length() will trigger a compile error):
int[] nums = {10, 20, 30, 40};
int len = nums.length; // Correct: direct field access
// int bad = nums.length(); // COMPILE ERROR: cannot find symbol method length()Why is length a field on arrays, but a method on Strings and Lists? - arr.length
(Field): The JVM allocates arrays with a fixed memory buffer. The length is stored directly as a
32-bit integer in the array's 16-byte object header and accessed via the direct CPU/bytecode
instruction arraylength with zero method-call overhead. - str.length() (Method): String
encapsulates an internal byte array (byte[] value) and requires an accessor method to respect
OOP encapsulation. - list.size() (Method): List and collections have dynamic capacities
that mutate over time.
Printing 1D Arrays in Java
A classic beginner and interview trap is attempting to print an array directly using System.out.println(arr):
int[] nums = {1, 2, 3};
System.out.println(nums); // Prints: [I@6828a2a8 (NOT [1, 2, 3]!)Why does this happen? Arrays do not override Object.toString(). Java inherits the default
implementation: getClass().getName() + "@" + Integer.toHexString(hashCode()). For int[], [I
signifies a 1D integer array followed by its hexadecimal memory identity hashcode.
Comprehensive Printing Methods
The standard and most idiomatic one-liner for 1D arrays:
import java.util.Arrays;
int[] nums = {10, 20, 30, 40};
System.out.println(Arrays.toString(nums));
// Output: [10, 20, 30, 40]
String[] words = {"Java", "DSA", "Guide"};
System.out.println(Arrays.toString(words));
// Output: [Java, DSA, Guide]Cloning & Copying 1D Arrays
High-level and concise; pads with zeros or truncates if newLength != orig.length:
int[] orig = {10, 20, 30};
// Exact copy
int[] copy = Arrays.copyOf(orig, orig.length); // [10, 20, 30]
// Padded copy
int[] padded = Arrays.copyOf(orig, 5); // [10, 20, 30, 0, 0]
// Slice copy [from, to)
int[] slice = Arrays.copyOfRange(orig, 1, 3); // [20, 30]Complexity Profile
| Operation | Time Complexity | Space Complexity | Notes / Invariants |
|---|---|---|---|
Index Access (arr[i]) | O(1) | O(1) | Direct offset calculation: base + (i * elementSize) |
| Search (Unsorted) | O(n) | O(1) | Linear scan |
| Search (Sorted) | O(log n) | O(1) | Binary search (Arrays.binarySearch) |
| Insert / Delete at Index | O(n) | O(1) | Requires shifting elements via System.arraycopy |
Dual-Pivot Quicksort (int[]) | O(n log n) | O(log n) | Unstable primitive sorting in Arrays.sort |
TimSort (Object[]) | O(n log n) | O(n) | Stable, adaptive sorting in Arrays.sort |
java.util.Arrays Toolkit
The primary static toolkit provided by the JDK for 1D arrays:
| Method / Property | Parameters | Return Type | Description / Notes |
|---|---|---|---|
arr.length | (property) | int | Public final field (NOT a method). Stored in JVM object header; read via arraylength bytecode |
Arrays.sort(arr) | (int[]|double[]|...) | void | Sorts primitives via Dual-Pivot Quicksort (O(n log n)) |
Arrays.sort(T[] a, Comparator c) | (T[] a, Comparator c) | void | Sorts objects via TimSort (O(n log n), stable) |
Arrays.parallelSort(arr) | (int[]|double[]|...) | void | Multi-core ForkJoinPool sort for arrays > 8192 items |
Arrays.binarySearch(arr, key) | (arr, key) | int | Precondition: array must be sorted. Returns index or -(insertion_point) - 1 |
Arrays.fill(arr, val) | (arr, val) | void | Assigns val to every slot |
Arrays.equals(a, b) | (a, b) | boolean | Element-by-element equality check |
Arrays.mismatch(a, b) | (a, b) | int | Returns index of first differing element, or -1 if identical (Java 9+) |
Arrays.stream(arr) | (arr) | IntStream / Stream<T> | Produces primitive or object stream |
Arrays.copyOf(arr, newLen) | (arr, int) | T[] | Returns truncated or zero-padded copy |
Arrays.copyOfRange(arr, from, to) | (arr, int, int) | T[] | Half-open slice copy [from, to) |
Arrays.asList(T... a) | (T... a) | List<T> | Fixed-size list wrapper backed by the array |
Binary Search Contract & Deriving Insertion Points
int[] nums = {10, 20, 30, 40, 50};
int found = Arrays.binarySearch(nums, 30); // returns 2
// Search for 25 (absent, belongs at index 2):
int absent = Arrays.binarySearch(nums, 25); // returns -(2) - 1 = -3
// Derive the correct insertion point:
int insertionPoint = -absent - 1; // 2The Arrays.asList() Traps
// Trap 1: Fixed-size list view backed by the original array
String[] names = {"Alice", "Bob"};
List<String> list = Arrays.asList(names);
// list.add("Charlie"); // Throws UnsupportedOperationException!
list.set(0, "Alex"); // Mutates the backing 'names' array!
// Trap 2: Primitive array autoboxing failure
int[] nums = {1, 2, 3};
List<int[]> badList = Arrays.asList(nums); // Size is 1! Contains int[] object!
// Idiomatic conversion of primitive int[] to List<Integer>:
List<Integer> goodList = Arrays.stream(nums).boxed().toList(); // Java 16+