Java Tips | 基本ユーティリティ:Objects.deepEquals()

Web APP Java
スポンサーリンク
スポンサーリンク

Objects.deepEquals()とは何か

Javaで業務システムを開発していると、「2つのデータが同じ内容かどうか」を判定する場面が頻繁にあります。

例えば、

  • 更新前後のデータ比較
  • APIレスポンスの検証
  • テストコードでの結果比較
  • 配列データの一致判定
  • 設定情報の変更チェック

などです。

そのような比較処理で利用できるユーティリティメソッドが Objects.deepEquals() です。

Objects.deepEquals(比較対象1, 比較対象2)
Java

このメソッドは「深い比較(Deep Comparison)」を行います。

通常のequals()では比較しきれない配列の中身まで比較できるのが最大の特徴です。

特に業務システムでは、複数の値をまとめて保持する配列やデータ構造を扱うことが多いため、deepEquals()の役割を理解しておくと非常に役立ちます。

まずはObjects.equals()との違いを理解しよう

前回学んだ Objects.equals() はnull安全な比較メソッドでした。

// 文字列比較
boolean result =
        Objects.equals(
                "Java",
                "Java"
        );

System.out.println(result);
Java

実行結果

true

文字列や一般的なオブジェクト比較では十分です。

しかし配列になると話が変わります。

配列比較で発生する問題

次のコードを見てみましょう。

// 配列を作成
String[] array1 = {"A", "B", "C"};
String[] array2 = {"A", "B", "C"};

// 比較
System.out.println(
        Objects.equals(
                array1,
                array2
        )
);
Java

実行結果

false

初心者の方は驚くかもしれません。

中身は同じなのにfalseになっています。

これはObjects.equals()が配列の中身ではなく、「配列オブジェクトそのもの」を比較しているためです。

Objects.deepEquals()が問題を解決する

同じコードをdeepEquals()で書いてみましょう。

// 配列作成
String[] array1 = {"A", "B", "C"};
String[] array2 = {"A", "B", "C"};

// 深い比較
boolean result =
        Objects.deepEquals(
                array1,
                array2
        );

System.out.println(result);
Java

実行結果

true

今度はtrueになります。

deepEquals()は配列の中身まで比較してくれるからです。

「深い比較」とは何か

初心者向けに簡単に説明すると、

  • 浅い比較(Shallow Comparison) → 箱そのものを比較
  • 深い比較(Deep Comparison) → 箱の中身まで比較

という違いがあります。

例えば次のようなイメージです。


箱A → [A, B, C]
箱B → [A, B, C]

浅い比較では、


箱A と 箱B

が別物なのでfalseになります。

深い比較では、


A, B, C
A, B, C

まで確認するためtrueになります。

ステップバイステップで理解する

ステップ1:比較対象を作成する

// 配列作成
String[] data1 =
        {"Java", "Python"};

String[] data2 =
        {"Java", "Python"};
Java

ステップ2:deepEquals()で比較する

// 配列内容比較
boolean matched =
        Objects.deepEquals(
                data1,
                data2
        );
Java

ステップ3:結果を確認する

// 結果表示
System.out.println(matched);
Java

実行結果

true

配列の中身が一致しているためtrueになります。

nullにも安全に対応している

Objects系メソッドなので、null比較にも対応しています。

// 両方null
System.out.println(
        Objects.deepEquals(
                null,
                null
        )
);
Java

実行結果

true

両方ともnullなのでtrueです。

// 片方null
System.out.println(
        Objects.deepEquals(
                null,
                "Java"
        )
);
Java

実行結果

false

片方だけnullなのでfalseになります。

多次元配列でも利用できる

deepEquals()の真価はここにあります。

多次元配列の比較まで自動で行ってくれます。

// 二次元配列
String[][] data1 = {
        {"A", "B"},
        {"C", "D"}
};

String[][] data2 = {
        {"A", "B"},
        {"C", "D"}
};

// 深い比較
boolean result =
        Objects.deepEquals(
                data1,
                data2
        );

System.out.println(result);
Java

実行結果

true

配列の奥にある要素まで比較してくれます。

実務でよくある利用例

設定情報変更チェック

// 更新前
String[] oldRoles =
        {"ADMIN", "USER"};

// 更新後
String[] newRoles =
        {"ADMIN", "USER"};

// 差分確認
if (Objects.deepEquals(
        oldRoles,
        newRoles
)) {

    System.out.println("変更なし");
}
Java

権限情報や設定情報の比較で利用されます。

テストコードの検証

// 期待値
String[] expected =
        {"A", "B", "C"};

// 実際の値
String[] actual =
        {"A", "B", "C"};

// 結果確認
assert Objects.deepEquals(
        expected,
        actual
);
Java

自動テストでよく見かける使い方です。

APIレスポンス比較

// 前回取得データ
String[] oldData =
        apiResult1;

// 最新データ
String[] newData =
        apiResult2;

// 差分確認
if (!Objects.deepEquals(
        oldData,
        newData
)) {

    updateCache();
}
Java

キャッシュ更新処理などで活用されます。

Objects.equals()との使い分け

Objects.equals()

// 通常比較
Objects.equals(
        value1,
        value2
);
Java

文字列やオブジェクト比較向きです。

Objects.deepEquals()

// 深い比較
Objects.deepEquals(
        array1,
        array2
);
Java

配列やネストしたデータ比較向きです。

通常のString比較などでdeepEquals()を使う必要はほとんどありません。

初心者が間違えやすいポイント

すべてのオブジェクトを再帰的に比較するわけではない

deepEquals()は主に配列比較で効果を発揮します。

独自クラスの場合は、そのクラスのequals()実装に依存します。

// 独自クラス
User u1 = new User();
User u2 = new User();

// equals未実装なら期待通りにならない場合がある
Objects.deepEquals(u1, u2);
Java

ドメインクラスではequals()を適切に実装することが重要です。

リスト比較では別の選択肢もある

Listの場合は通常のequals()が要素比較を行います。

// List比較
Objects.equals(
        list1,
        list2
);
Java

そのためdeepEquals()が必須とは限りません。

主な用途は配列比較だと覚えておくと良いでしょう。

実務で使えるテンプレート集

配列一致チェック

// 配列比較
boolean matched =
        Objects.deepEquals(
                array1,
                array2
        );
Java

更新判定

// 差分検出
if (!Objects.deepEquals(
        oldValues,
        newValues
)) {

    // 更新処理
}
Java

テスト検証

// 結果比較
assert Objects.deepEquals(
        expected,
        actual
);
Java

null安全比較

// nullも比較可能
boolean result =
        Objects.deepEquals(
                value1,
                value2
        );
Java

情報セキュリティの観点から見る重要性

業務システムでは設定情報や権限情報、キャッシュデータなどの比較処理が数多く存在します。

もし誤った比較方法を使用すると、

  • 更新漏れ
  • 不要な更新処理
  • キャッシュ不整合
  • 権限設定反映漏れ
  • 監査データ不整合

といった問題につながる可能性があります。

deepEquals()を正しく利用することで、配列データの比較精度を向上させることができます。

特に構成情報やアクセス権情報を配列で保持しているシステムでは、正確な比較処理が重要になります。

初心者が覚えておくべき重要ポイント

  • 配列の中身まで比較できる
  • null安全に比較できる
  • 多次元配列にも対応している
  • Objects.equals()より深い比較を行う
  • テストコードでよく利用される
  • 更新判定や差分検出に役立つ
  • 主な用途は配列比較である

まとめ

Objects.deepEquals()は、Java標準ライブラリが提供する深い比較を行うユーティリティメソッドです。

  • 配列の中身まで比較できる
  • null安全な比較が可能
  • 多次元配列の比較にも対応する
  • Objects.equals()では判定できないケースを補える
  • 差分チェックや更新判定に役立つ
  • テストコードでも頻繁に利用される
  • 業務システムのデータ比較精度向上に貢献する

特に業務開発では、「データそのものが同じか」を正確に判定することが重要です。Objects.deepEquals()は、配列や複雑なデータ構造を扱う際に安全かつ簡潔な比較処理を実現できる便利なユーティリティであり、Objects.equals()との違いを理解して使い分けることで、より堅牢なJavaコードを書けるようになります。

タイトルとURLをコピーしました