今回は、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