equals(), toString() & Streams
Arrays.equals(a, b) — element-wise comparison (use Arrays.deepEquals for 2D). Arrays.toString(arr) prints '[1, 2, 3]'. Arrays.deepToString for nested arrays. Arrays.stream(arr) enables sum(), max(), filter(), distinct(), and collect().
How It Works
Arrays.equals(a, b) compares two arrays element by element — unlike ==, which only tests reference identity, or a.equals(b), which arrays inherit unchanged from Object. Nested arrays need Arrays.deepEquals, which recurses into sub-arrays. The same split applies to printing: Arrays.toString(arr) renders '[1, 2, 3]' while Arrays.deepToString handles 2D arrays, and printing an array directly yields a useless hash-like identifier.
Arrays.stream(arr) opens the functional toolbox on primitives: sum(), max(), min(), average() as terminal operations, and filter, map, distinct, sorted as intermediate ones. These are O(n) conveniences, not asymptotic wins — their value is expressing frequency counts, aggregates, and transformations in a line rather than a loop.
Step-by-Step Visualization
Code
int[] a = {1, 2, 3};
int[][] m1 = {{1, 2}, {3, 4}};
int[][] m2 = {{1, 2}, {3, 4}};
// ─── Comparison ───────────────────────────────────────────────
Arrays.equals(a, b); // true — element-wise (1D)
Arrays.equals(m1, m2); // false — compares row references!
Arrays.deepEquals(m1, m2); // true — recursive element-wise (2D+)
// ─── Print ────────────────────────────────────────────────────
Arrays.toString(a); // "[1, 2, 3]"
Arrays.deepToString(m1); // "[[1, 2], [3, 4]]"
// ─── Streams (IntStream — no boxing) ─────────────────────────
Arrays.stream(a).sum(); // 6
Arrays.stream(a).max().getAsInt(); // 3
Arrays.stream(a).min().getAsInt(); // 1
Arrays.stream(a).filter(x -> x > 1).count(); // 2
Arrays.stream(a).distinct().toArray(); // dedup
// ─── Useful one-liners ────────────────────────────────────────
// int[] → String[]
String[] strs = Arrays.stream(a).mapToObj(Integer::toString).toArray(String[]::new);
// prefix sum in-place
int[] pre = new int[a.length + 1];
Arrays.setAll(pre, i -> i == 0 ? 0 : pre[i - 1] + a[i - 1]);Tips & Gotchas
Practice Problems
- 1Running Sum of 1d Array
- 2Richest Customer Wealth
- 3Valid Anagram
- 4Maximum Subarray
About the Arrays Utility API Pattern
java.util.Arrays methods and array ↔ collection conversion patterns. These utilities handle sorting, searching, copying, filling, and bridging between primitive arrays and Java collections.
When you see 'subarray', 'contiguous', or 'in-place', think arrays. The key is reducing brute-force O(n²) to O(n) using sliding window, two pointers, or prefix sums.
Common Array Interview Problems
- Two Sum
- Best Time to Buy & Sell Stock
- Maximum Subarray
- Merge Intervals
- Product of Array Except Self
- Container With Most Water
Frequently Asked Questions
Why does array1 == array2 return false even when contents match?
The == operator compares references, asking whether both variables point to the same object in memory. Content comparison requires Arrays.equals for one-dimensional arrays or Arrays.deepEquals for nested ones; arrays never override Object.equals, so a.equals(b) is just == in disguise.
When should I use streams versus a plain loop on arrays in interviews?
Streams shine for quick aggregates — Arrays.stream(nums).sum() or .max().getAsInt() — and keep setup code short. Inside hot loops or when the interviewer probes performance, a plain for-loop avoids boxing and lambda overhead and is easier to reason about step by step.
How do I print a 2D array for debugging?
Use Arrays.deepToString(matrix), which recursively formats nested arrays into readable brackets. Arrays.toString on a 2D array prints the hash-like identity of each row rather than its contents, which is a common source of confusing debug output.