【Java】複数(3つ以上)のListを結合する方法

こんにちは、エキサイト株式会社の蝦名です。

エキサイトHDアドベントカレンダー19日目の記事です。
qiita.com 是非、他の記事もチェックしてみてください!

この記事について

複数のListを結合する方法についてです。
2つのListを結合する方法は、以前taanatsuさんの記事で紹介されていました!

tech.excite.co.jp

そこで、もっと多くのListを結合する場合にはどんな方法があるだろう?と考えてみました。

本題

前提環境

1. Stream.concat()で結合していく方法

まず思いついた方法です。
今回はサンプルコードとして、複数のListをStream.concat()で結合するメソッドを作成してみました。

public List<String> sample() {
    List<String> mergedList = mergeListMultiple(
            List.of("a"),
            List.of("b"),
            List.of("c")
    );
    return mergedList;

}

private <T> List<T> mergeListMultiple(List<T>... list) {
    List<T> mergedList = List.of();
    for (List<T> tlist : list) {
        mergedList = Stream.concat(
                mergedList.stream(),
                tlist.stream()
        ).toList();
    }
    return mergedList;

}

作ってはみたものの、結合したいListの数だけListが生成されてしまうため、多くのListを結合するには向いてなさそうですね。

2. List.addAll()で結合していく方法

Stream.concat()をList.addAll()で置き換えてみました。
Listがたくさん生成されてしまう問題は解決しましたね。

public List<String> sample() {
    List<String> mergedList = mergeListMultiple(
            List.of("a"),
            List.of("b"),
            List.of("c")
    );
    return mergedList;

}

private <T> List<T> mergeListMultiple(List<T>... list) {
    List<T> mergedList = new ArrayList<>();
    for (List<T> tlist : list) {
        mergedList.addAll(tlist);
    }
    return List.copyOf(mergedList);

}

さらに応用として、Stream.forEach()を使用してみました。
Streamの副作用を利用しています。

List<List<String>> stringListList = List.of(
        List.of("a"),
        List.of("b"),
        List.of("c")
);

List<String> mergedList = new ArrayList<>();
stringListList.stream()
        .forEach(
                list -> mergedList.addAll(list)
        );

この場合、mergedListはmutableなListなので注意が必要です。
必要に応じてList.copyOf()を使用し、immutableなListを生成しましょう。

3. Stream.flatMap()で結合する方法

Streamを使用する方法をさらに応用できないかと考えた結果がこちらです。

List<List<String>> stringListList = List.of(
        List.of("a"),
        List.of("b"),
        List.of("c")
);

List<String> mergedList = stringListList.stream()
        .flatMap(
                list -> list.stream()
        )
        .toList();

綺麗な形に収まりましたね。
実際にはこちらの方法が本命になるかと思います。

まとめ

色々と試行錯誤するのは楽しいですね!
皆さんも、それぞれの方法のメリット/デメリット、他の方法など思いついたら是非教えてください!

最後に

エキサイトHDアドベントカレンダーはまだ続きます!明日もお楽しみに!

qiita.com