Java
Arrays
equals method
Arrays.equals
Java programming

equals vs Arrays.equals in Java

Data Structures & Algorithms practice on Codemia

Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.

Practice algorithms

Introduction

Java has two very different equality stories: object equality through equals, and array content equality through helpers in java.util.Arrays. Confusion usually happens because arrays are objects, but their inherited equals method still compares references rather than elements.

What Plain equals Does

Every Java class inherits equals from Object. If a class does not override it, the default behavior is reference equality.

java
1public class EqualsDemo {
2    public static void main(String[] args) {
3        String[] a = {"x", "y"};
4        String[] b = {"x", "y"};
5
6        System.out.println(a.equals(b)); // false
7        System.out.println(a == b);      // false
8    }
9}

Both lines print false because a and b refer to different array instances.

For ordinary domain objects, developers often override equals to describe logical identity.

java
1import java.util.Objects;
2
3final class Point {
4    private final int x;
5    private final int y;
6
7    Point(int x, int y) {
8        this.x = x;
9        this.y = y;
10    }
11
12    @Override
13    public boolean equals(Object other) {
14        if (this == other) return true;
15        if (!(other instanceof Point point)) return false;
16        return x == point.x && y == point.y;
17    }
18
19    @Override
20    public int hashCode() {
21        return Objects.hash(x, y);
22    }
23}

That is the normal use of equals: defining value semantics for a class you control.

Why Arrays Need Arrays.equals

Arrays are special because you do not override their methods. If you want element-by-element comparison, use Arrays.equals.

java
1import java.util.Arrays;
2
3public class ArrayEqualsDemo {
4    public static void main(String[] args) {
5        int[] left = {1, 2, 3};
6        int[] right = {1, 2, 3};
7
8        System.out.println(left.equals(right));         // false
9        System.out.println(Arrays.equals(left, right)); // true
10    }
11}

Arrays.equals walks both arrays in order and compares corresponding elements. For primitive arrays it compares raw values. For object arrays it calls equals on each element.

java
1import java.util.Arrays;
2
3public class ObjectArrayEqualsDemo {
4    public static void main(String[] args) {
5        String[] first = {"red", "blue"};
6        String[] second = {"red", "blue"};
7
8        System.out.println(Arrays.equals(first, second)); // true
9    }
10}

This means the correctness of object-array comparison depends on the element type implementing equals sensibly.

Use Arrays.deepEquals for Nested Arrays

Arrays.equals is still shallow for nested arrays. If the elements are themselves arrays, use Arrays.deepEquals.

java
1import java.util.Arrays;
2
3public class DeepEqualsDemo {
4    public static void main(String[] args) {
5        int[][] a = {{1, 2}, {3, 4}};
6        int[][] b = {{1, 2}, {3, 4}};
7
8        System.out.println(Arrays.equals(a, b));      // false
9        System.out.println(Arrays.deepEquals(a, b));  // true
10    }
11}

This distinction matters in matrix code, parsed JSON-like structures, and tests that compare nested data.

Pick the Right Equality Tool

A simple rule helps:

  • compare ordinary objects with their equals implementation
  • compare one-dimensional arrays with Arrays.equals
  • compare nested arrays with Arrays.deepEquals

If you find yourself repeatedly comparing arrays inside a domain type, it may be cleaner for that type to implement its own equals and delegate to Arrays.equals internally.

java
1import java.util.Arrays;
2
3final class ScoreRow {
4    private final int[] scores;
5
6    ScoreRow(int[] scores) {
7        this.scores = Arrays.copyOf(scores, scores.length);
8    }
9
10    @Override
11    public boolean equals(Object other) {
12        if (this == other) return true;
13        if (!(other instanceof ScoreRow row)) return false;
14        return Arrays.equals(scores, row.scores);
15    }
16
17    @Override
18    public int hashCode() {
19        return Arrays.hashCode(scores);
20    }
21}

That keeps equality logic close to the type that owns the data.

Common Pitfalls

  • Calling array.equals(otherArray) and expecting element comparison returns reference equality instead.
  • Overriding equals without also overriding hashCode breaks collections such as HashMap and HashSet.
  • Using Arrays.equals on nested arrays gives surprising false results because the comparison is shallow.
  • Forgetting that object-array comparison depends on element equals behavior leads to inconsistent results.
  • Using == for strings or boxed values compares references, not logical contents.

Summary

  • Default equals from Object compares references unless a class overrides it.
  • Arrays do not override equals, so array.equals(...) is usually the wrong choice.
  • Use Arrays.equals for one-dimensional array content comparison.
  • Use Arrays.deepEquals for nested arrays.
  • When arrays are part of a value object, delegate to Arrays.equals and Arrays.hashCode inside that type.

Related reading
Course
Intermediate
27 lessons
15 hours
DSA Fundamentals

Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Data Structures & Algorithms practice on Codemia

Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.

Practice algorithms

All Rights Reserved.