【Java】2次元配列の重複削除を徹底解説|初心者向けサンプル付き

お疲れ様です。はるさらと申します。

Javaで2次元配列を扱う際に、同じ行データが重複してしまうことがあります。
例えば、CSVファイルを読み込んだときや、
外部からデータを集計したときに「同じ行が何度も入ってしまった」というケースです。

そのままでは正しい集計や処理ができないため、
2次元配列から重複を削除する方法を理解しておく必要があります。

この記事では、2次元配列の重複削除を実現する方法を、
基本例・実務利用例・代替手法比較の3パターンで解説します。
経験の浅い方でも理解できるよう、
具体的なサンプルコードを交えて説明していきます。


2次元配列の重複削除の考え方

まず前提として、Javaの2次元配列には
「行を比較して重複を判定する便利なメソッド」は用意されていません。
そのため、以下のような方法を使って重複を削除していきます。

  • Setを使って一意の要素だけを残す
  • Stream APIでdistinctを利用する
  • 手動でループを回して判定する

配列そのままではequals比較ができないため、
文字列変換して比較する方法Listに変換する方法をよく使います。


基本例:Setを使って重複を削除する方法

最もシンプルな方法は、各行を文字列化してSetに格納するやり方です。
Setは重複を許さないため、同じ行が自動的に排除されます。

import java.util.*;

public class RemoveDuplicatesBasic {
    public static void main(String[] args) {
        String[][] data = {
            {"001", "田中", "営業"},
            {"002", "佐藤", "開発"},
            {"001", "田中", "営業"}, // 重複
            {"003", "鈴木", "総務"}
        };

        // Setを使って重複を排除
        Set<String> uniqueSet = new LinkedHashSet<>();
        for (String[] row : data) {
            uniqueSet.add(Arrays.toString(row));
        }

        // Setから配列に戻す
        String[][] result = new String[uniqueSet.size()][];
        int i = 0;
        for (String s : uniqueSet) {
            // "[001, 田中, 営業]" を配列に変換
            s = s.replaceAll("[\\[\\]]", "");
            result[i++] = s.split(", ");
        }

        // 出力確認
        for (String[] row : result) {
            System.out.println(Arrays.toString(row));
        }
    }
}

実行結果:

[001, 田中, 営業]
[002, 佐藤, 開発]
[003, 鈴木, 総務]

この方法は、行全体を文字列にして比較するのでシンプルで分かりやすいです。


実務利用例:Listを使って重複削除

実務では、2次元配列をそのまま使うより
List<List<>>に変換して扱うケースが多いです。
その場合は、contains()を使って簡単に重複判定ができます。

import java.util.*;

public class RemoveDuplicatesList {
    public static void main(String[] args) {
        String[][] data = {
            {"001", "田中", "営業"},
            {"002", "佐藤", "開発"},
            {"001", "田中", "営業"}, // 重複
            {"003", "鈴木", "総務"}
        };

        List<List<String>> uniqueList = new ArrayList<>();

        for (String[] row : data) {
            List<String> rowList = Arrays.asList(row);
            if (!uniqueList.contains(rowList)) {
                uniqueList.add(rowList);
            }
        }

        // 出力確認
        for (List<String> row : uniqueList) {
            System.out.println(row);
        }
    }
}

実行結果:

[001, 田中, 営業]
[002, 佐藤, 開発]
[003, 鈴木, 総務]

この方法は、可変長のリストを使うため、
後から追加・削除にも対応しやすいのが特徴です。
業務でCSVやデータベースの結果を処理する場合に特に有効です。


代替手法:Stream APIで重複削除する方法

Java 8以降では、Stream APIを使ってdistinct()で重複削除する方法もあります。
可読性が高く、処理がシンプルになります。

import java.util.*;
import java.util.stream.Collectors;

public class RemoveDuplicatesStream {
    public static void main(String[] args) {
        String[][] data = {
            {"001", "田中", "営業"},
            {"002", "佐藤", "開発"},
            {"001", "田中", "営業"}, // 重複
            {"003", "鈴木", "総務"}
        };

        List<List<String>> uniqueList = Arrays.stream(data)
            .map(Arrays::asList)
            .distinct()
            .collect(Collectors.toList());

        // 出力確認
        uniqueList.forEach(System.out::println);
    }
}

実行結果:

[001, 田中, 営業]
[002, 佐藤, 開発]
[003, 鈴木, 総務]

Stream APIを使うと、1行で重複削除を表現できるので、
コード量を減らしたい場合に便利です。


注意点:経験の浅い方が間違えやすいポイント

2次元配列の重複削除では、いくつか注意点があります。

  1. 配列同士の比較は==ではできない if (arr1 == arr2) // 参照比較になってしまう
    Arrays.equals()やList変換を使う必要があります。
  2. Arrays.asListの使い方に注意
    Arrays.asList(row)で得られるリストは固定長のため、
    直接要素の追加・削除はできません。
    → 必要ならnew ArrayList<>(Arrays.asList(row))に変換しましょう。
  3. 順序を保持したいならLinkedHashSetを使う
    通常のHashSetだと順序が保証されないため、
    順番を保ちたい場合はLinkedHashSetが適しています。

関連記事

2次元配列に関する他の記事もあわせて参考にしてください。


まとめ

  • Javaの配列は直接比較できないため、List変換や文字列化で重複判定する
  • 基本はSetを利用する方法、実務ではListやStream APIが便利
  • 配列の比較は==ではなく内容比較を意識することが重要
  • 順序保持や追加・削除の要件に応じて方法を使い分ける

経験の浅い方は、まずはSetを使った基本例を試し、
その後ListやStream APIで効率的に
重複削除できるようになると実務でも役立ちます。

どなたかのお役に立てば幸いです。
それではまたー!