Javaで重複を排除する3つの方法

java

今回は、javaでListの重複排除を行う方法を3つ紹介します。

1つ目の方法は、for文で自力でアルゴリズムを記述して重複排除を行う方法です。
記述が冗長になり、コーディングミスも起こりやすいことから、現在の実務ではこの方法で重複排除を行うことはないと思います。
しかし、新人研修でjavaの標準APIの学習が不十分な段階で使うケースが想定される他、実務でもCOBOLからjavaにコンバージョンしている等のレガシーな環境では見かけることがあるかもしれません。

2つ目の方法は、HashSet(順番を保証する必要がある場合はLinkedHashSet)を使用する方法です。
HashSetとは、重複を排除して要素を格納するクラスであり、自力で重複排除のアルゴリズムを記述する必要がないためコーディングミスは起こりにくいです。
コンストラクタでListとSetの相互変換も可能であることもあり、記述も簡潔になります。
実務ではHashSetを使うケースが多いと思います。

3つ目の方法は、StreamAPIを使用する方法です。
StreamAPIにはdistinctメソッドが用意されており、このメソッドを呼び出すことで重複排除が可能です。
Java8から導入された機能であり、背景に関数型プログラミングの考え方があることから、昔からjavaを書いてきた人は取っつきにくさを感じるかもしれません。
しかし、新しい物好きの現場ではStreamAPIの使用が好まれるでしょう。

以下、サンプルコードです。

【サンプルコード】

import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

public class DistinctMain {

    public static void main(String[] args) {

        // 重複排除前のList
        List<Integer> beforeList = new ArrayList<Integer>();
        beforeList.add(1);
        beforeList.add(3);
        beforeList.add(2);
        beforeList.add(4);
        beforeList.add(3);
        beforeList.add(2);
        beforeList.add(1);

        // 重複排除後のList
        // 期待結果:1→3→2→4
        List<Integer> afterList1;
        List<Integer> afterList2;
        List<Integer> afterList3;

        // for文で重複排除
        // 値を一つ一つ抽出、未抽出の値なら出力のListに詰め、抽出済の値なら無視
        afterList1 = new ArrayList<Integer>();
        for (int i = 0; i < beforeList.size(); i++) {
            int item = beforeList.get(i);
            int j = 0;
            for (; j < afterList1.size(); j++) {
                if (item == afterList1.get(j)) {
                    break;
                }
            }
            if (j == afterList1.size()) {
                afterList1.add(item);
            }
        }

        // LinkedHashSetで重複排除(HashSetだと順番が保証されない)
        // コンストラクタを利用してList→Set(重複排除)→Listの変換
        Set<Integer> tmpSet = new LinkedHashSet<Integer>(beforeList);
        afterList2 = new ArrayList<Integer>(tmpSet);

        // StreamAPIで重複排除
        // Streamに変換→distinctメソッドで重複排除→Listに変換
        afterList3 = beforeList.stream()
                               .distinct()
                               .collect(Collectors.toList());

        // 重複排除結果の確認
        System.out.println("[for文で重複排除]");
        for (int item : afterList1) {
            System.out.println(item);
        }
        System.out.println("[LinkedHashSetで重複排除]");
        for (int item : afterList2) {
            System.out.println(item);
        }
        System.out.println("[StreamAPIで重複排除]");
        for (int item : afterList3) {
            System.out.println(item);
        }

    }

}

【実行結果】

[for文で重複排除]
1
3
2
4
[LinkedHashSetで重複排除]
1
3
2
4
[StreamAPIで重複排除]
1
3
2
4

いかがでしたでしょうか。

新人研修で重複排除の方法が話題になったので、この記事を書いてみました。

javaは歴史の長い言語であるため、一つのことを実現するだけでも色々と書き方があります。
また、今回紹介したように、時と場合により、どのような書き方をするか使い分けすることが望ましいです。

コメント

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