Comparing & printing arrays in Java
== and equals compare references; use Arrays.equals and Arrays.toString.
equals isn't overridden
Arrays **don't override equals: they inherit Object's version, which asks "same object?"**. So a == b and a.equals(b) both compare references. To compare contents, use **Arrays.equals(a, b)**: it checks the length and each element.
int[] a = {1, 2}, b = {1, 2};
a == b; // false
a.equals(b); // false!
Arrays.equals(a, b); // trueYour turn
What prints?
int[] a = {5, 6};
int[] b = {5, 6};
int[] c = a;
System.out.println(a == b);
System.out.println(a.equals(c));
System.out.println(Arrays.equals(a, b));false true truefalse false truetrue true truefalse true false
Show the answer
a and b are different objects: false. c is a (same reference), so even Object's equals says true. Arrays.equals compares contents: true.
Printing gibberish
Arrays don't override toString either. println(arr) shows Object's default: a type code ([I means int array), an @, and a hash code in hex, like [I@6d06d69c. Use **Arrays.toString**. One exception: println has a special overload for **char[]** that prints the characters as text.
int[] n = {1, 2};
System.out.println(n); // [I@6d06d69c
System.out.println(Arrays.toString(n));
// [1, 2]The char[] exception
What prints?
char[] w = {'o', 'k'};
System.out.println(w);
System.out.println(Arrays.toString(w));ok [o, k][o, k] [o, k]ok ok
Show the answer
println(char[]) is a dedicated overload that prints the characters as text: ok. Arrays.toString always uses the bracketed list format.
Nested arrays need deep
Arrays.equals on 2-D arrays compares the rows using their equals, and rows are arrays, so that's a reference check: false. Use **Arrays.deepEquals** to go inside nested arrays (and deepToString to print them).
int[][] x = {{1}, {2}};
int[][] y = {{1}, {2}};
Arrays.equals(x, y); // false
Arrays.deepEquals(x, y); // trueChecking a result in a test
if (expected == actual) ...
if (expected.equals(actual)) ...
if (Arrays.toString(expected)
== Arrays.toString(actual)) ...All three compare references. The toString version builds two different String objects and compares them with ==.
if (Arrays.equals(expected, actual)) {
System.out.println("pass");
}Compares length and every element. (Comparing only lengths would ignore the contents.)
In real projects
Test frameworks know this trap: JUnit has assertArrayEquals because assertEquals on two arrays compares references. And if your logs ever show [I@..., someone printed an array directly instead of using Arrays.toString.
Key takeaways
- a == b and a.equals(b) both compare references
- Arrays.equals compares the elements of 1-D arrays
- Arrays.deepEquals for nested arrays
- Printing an array directly shows type code + hash, e.g. [I@1b6d3586
The cryptic codes tell you the type: [I is int[], [[I is int[][], [D is double[], and [Ljava.lang.String; is String[].
Practice questions
System.out.println(new int[]{1, 2}) prints something like [I@6d06d69c. What is that?
- The memory address of each element
- Object's default toString: a type code ([I means int array), @ and a hash code in hex
- A sign that the array is corrupted
- The array's contents encoded in hexadecimal
Check your answer
Object's default toString: a type code ([I means int array), @ and a hash code in hex. Arrays don't override toString, so you get Object's version. Use Arrays.toString to see the elements.
What does this print?
int[] a = {1, 2};
int[] b = {1, 2};
System.out.println(a == b);
System.out.println(a.equals(b));
System.out.println(Arrays.equals(a, b));- false false true
- false true true
- true true true
- false false false
Check your answer
false false true. a and b are two different array objects. == and equals both compare references; only Arrays.equals compares the elements.