Stream

Java – Streamで2つのListを結合する方法

JavaのStreamを使用して2つのListを結合するには、Stream.concat()メソッドを利用します。

このメソッドは2つのStreamを結合し、新しいStreamを生成します。

結合後のStreamをcollect(Collectors.toList())でリストに変換することで、2つのListを1つにまとめることができます。

例えば、List<String> list1List<String> list2を結合する場合、Stream.concat(list1.stream(), list2.stream()).collect(Collectors.toList())と記述します。

Streamを使って2つのListを結合する方法

JavaのStream APIを使用すると、2つのListを簡単に結合することができます。

ここでは、Listを結合する基本的な方法を解説します。

具体的には、Stream.concat()メソッドを使用します。

以下にサンプルコードを示します。

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;
public class App {
    public static void main(String[] args) {
        // 1つ目のListを作成
        List<String> list1 = new ArrayList<>();
        list1.add("りんご");
        list1.add("ばなな");
        // 2つ目のListを作成
        List<String> list2 = new ArrayList<>();
        list2.add("オレンジ");
        list2.add("ぶどう");
        // 2つのListをStreamを使って結合
        Stream<String> combinedStream = Stream.concat(list1.stream(), list2.stream());
        // 結合したStreamをListに変換
        List<String> combinedList = combinedStream.toList();
        // 結合したListを出力
        System.out.println(combinedList);
    }
}
[りんご, ばなな, オレンジ, ぶどう]

このコードでは、まず2つのListを作成し、それぞれに果物の名前を追加しています。

次に、Stream.concat()メソッドを使用して2つのListを結合し、最終的に結合したStreamListに変換しています。

最後に、結合したListを出力しています。

この方法を使うことで、簡単に複数のListを結合することができ、可読性の高いコードを書くことができます。

応用的なList結合の方法

Streamを使ったListの結合には、さまざまな応用方法があります。

ここでは、条件に基づいてListを結合する方法や、重複を排除して結合する方法について解説します。

条件に基づくListの結合

特定の条件を満たす要素だけを結合する場合、filter()メソッドを使用します。

以下のサンプルコードでは、特定の文字列を含む要素だけを結合しています。

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;
public class App {
    public static void main(String[] args) {
        // 1つ目のListを作成
        List<String> list1 = new ArrayList<>();
        list1.add("りんご");
        list1.add("ばなな");
        list1.add("いちご");
        // 2つ目のListを作成
        List<String> list2 = new ArrayList<>();
        list2.add("オレンジ");
        list2.add("ぶどう");
        list2.add("いちご");
        // "いちご"を含む要素だけを結合
        Stream<String> combinedStream = Stream.concat(list1.stream(), list2.stream())
                                              .filter(fruit -> fruit.contains("いちご"));
        // 結合したStreamをListに変換
        List<String> combinedList = combinedStream.toList();
        // 結合したListを出力
        System.out.println(combinedList);
    }
}
[いちご, いちご]

このコードでは、filter()メソッドを使用して、”いちご”を含む要素だけを結合しています。

重複を排除してListを結合

重複を排除したい場合は、distinct()メソッドを使用します。

以下のサンプルコードでは、重複する要素を排除して結合しています。

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;
public class App {
    public static void main(String[] args) {
        // 1つ目のListを作成
        List<String> list1 = new ArrayList<>();
        list1.add("りんご");
        list1.add("ばなな");
        list1.add("いちご");
        // 2つ目のListを作成
        List<String> list2 = new ArrayList<>();
        list2.add("オレンジ");
        list2.add("ぶどう");
        list2.add("いちご"); // 重複要素
        // 重複を排除してListを結合
        Stream<String> combinedStream = Stream.concat(list1.stream(), list2.stream())
                                              .distinct();
        // 結合したStreamをListに変換
        List<String> combinedList = combinedStream.toList();
        // 結合したListを出力
        System.out.println(combinedList);
    }
}
[りんご, ばなな, いちご, オレンジ, ぶどう]

このコードでは、distinct()メソッドを使用して、重複する要素を排除しています。

これにより、結合したListには一意の要素のみが含まれます。

これらの応用方法を使うことで、より柔軟にListを結合することができ、さまざまな条件に対応したデータ処理が可能になります。

Streamを使ったList結合の注意点

JavaのStream APIを使用してListを結合する際には、いくつかの注意点があります。

これらを理解しておくことで、より効率的でエラーの少ないコードを書くことができます。

以下に主な注意点を挙げます。

Streamは一度しか使用できない

Streamは一度しか操作できないため、同じStreamを再利用することはできません。

再度使用する場合は、新たにStreamを生成する必要があります。

以下の例を見てみましょう。

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;
public class App {
    public static void main(String[] args) {
        List<String> list1 = new ArrayList<>();
        list1.add("りんご");
        list1.add("ばなな");
        List<String> list2 = new ArrayList<>();
        list2.add("オレンジ");
        list2.add("ぶどう");
        // Streamを結合
        Stream<String> combinedStream = Stream.concat(list1.stream(), list2.stream());
        // 最初の操作
        combinedStream.forEach(System.out::println);
        // 再度使用しようとするとエラーになる
        // combinedStream.forEach(System.out::println); // ここでエラー
    }
}

このコードでは、最初のforEachメソッドでStreamを消費した後、再度同じStreamを使用しようとするとエラーが発生します。

再利用する場合は、再度Stream.concat()を呼び出す必要があります。

結合後のStreamの操作

Streamを結合した後に、さらに操作を行う場合は、結合したStreamを適切に処理する必要があります。

例えば、結合したStreamに対してcollect()メソッドを使用する場合、結合後にすぐに結果を収集することが重要です。

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;
public class App {
    public static void main(String[] args) {
        List<String> list1 = new ArrayList<>();
        list1.add("りんご");
        list1.add("ばなな");
        List<String> list2 = new ArrayList<>();
        list2.add("オレンジ");
        list2.add("ぶどう");
        // Streamを結合
        Stream<String> combinedStream = Stream.concat(list1.stream(), list2.stream());
        // 結合したStreamをListに変換
        List<String> combinedList = combinedStream.toList(); // ここで結果を収集
        // 結合したListを出力
        System.out.println(combinedList);
    }
}

パフォーマンスへの影響

Streamを使用することで、コードは簡潔になりますが、大量のデータを扱う場合はパフォーマンスに影響を与えることがあります。

特に、filter()map()などの中間操作を多用すると、処理が遅くなる可能性があります。

必要な操作だけを行うように心がけましょう。

Null要素の扱い

Streamを使用する際、Listにnull要素が含まれている場合、NullPointerExceptionが発生することがあります。

結合する前に、null要素を除外するか、適切に処理する必要があります。

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;
public class App {
    public static void main(String[] args) {
        List<String> list1 = new ArrayList<>();
        list1.add("りんご");
        list1.add(null); // null要素
        List<String> list2 = new ArrayList<>();
        list2.add("オレンジ");
        list2.add("ぶどう");
        // null要素を除外して結合
        Stream<String> combinedStream = Stream.concat(list1.stream().filter(fruit -> fruit != null), list2.stream());
        // 結合したStreamをListに変換
        List<String> combinedList = combinedStream.toList();
        // 結合したListを出力
        System.out.println(combinedList);
    }
}
[りんご, オレンジ, ぶどう]

これらの注意点を理解し、適切にStreamを使用することで、より効率的でエラーの少ないプログラムを作成することができます。

Stream以外のList結合方法との比較

Javaでは、Stream APIを使用してListを結合する方法の他にも、従来の方法でListを結合することができます。

ここでは、Streamを使った方法と、従来の方法(ループを使用した方法)を比較し、それぞれの利点と欠点を解説します。

Streamを使ったList結合

Streamを使用したListの結合は、コードが簡潔で可読性が高いのが特徴です。

以下のサンプルコードを見てみましょう。

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;
public class App {
    public static void main(String[] args) {
        List<String> list1 = new ArrayList<>();
        list1.add("りんご");
        list1.add("ばなな");
        List<String> list2 = new ArrayList<>();
        list2.add("オレンジ");
        list2.add("ぶどう");
        // Streamを使ってListを結合
        List<String> combinedList = Stream.concat(list1.stream(), list2.stream()).toList();
        // 結合したListを出力
        System.out.println(combinedList);
    }
}
[りんご, ばなな, オレンジ, ぶどう]

利点

  • 可読性: コードが簡潔で、意図が明確。
  • メソッドチェーン: 複数の操作を連続して行うことができる。
  • 並列処理: 大量のデータを扱う場合、並列処理が可能でパフォーマンス向上が期待できる。

欠点

  • 学習コスト: Stream APIに不慣れな場合、理解するのに時間がかかることがある。
  • パフォーマンス: 小規模なデータセットでは、オーバーヘッドが大きくなることがある。

従来の方法(ループを使用したList結合)

従来の方法では、forループを使用してListを結合します。

以下のサンプルコードを見てみましょう。

import java.util.ArrayList;
import java.util.List;
public class App {
    public static void main(String[] args) {
        List<String> list1 = new ArrayList<>();
        list1.add("りんご");
        list1.add("ばなな");
        List<String> list2 = new ArrayList<>();
        list2.add("オレンジ");
        list2.add("ぶどう");
        // 従来の方法でListを結合
        List<String> combinedList = new ArrayList<>(list1); // list1を初期化
        for (String fruit : list2) {
            combinedList.add(fruit); // list2の要素を追加
        }
        // 結合したListを出力
        System.out.println(combinedList);
    }
}
[りんご, ばなな, オレンジ, ぶどう]

利点

  • シンプルさ: 基本的なループを使用するため、理解しやすい。
  • 柔軟性: 条件に基づいて要素を追加するなど、細かい制御が可能。

欠点

  • 可読性: コードが長くなりがちで、意図が分かりにくくなることがある。
  • エラーの可能性: 手動で要素を追加するため、エラーが発生しやすい。

比較まとめ

方法可読性パフォーマンス学習コスト柔軟性
Streamを使用高い大規模データで向上中程度中程度
従来のループ方法低い小規模データで向上低い高い

Streamを使用した方法は、可読性が高く、メソッドチェーンを活用できるため、複雑な処理を簡潔に記述できます。

一方、従来のループを使用した方法は、シンプルで柔軟性が高いですが、可読性が低くなることがあります。

使用する場面に応じて、適切な方法を選択することが重要です。

まとめ

この記事では、JavaのStream APIを使用して2つのListを結合する方法や、応用的な結合方法、注意点、従来の方法との比較について詳しく解説しました。

Streamを利用することで、可読性が高く、効率的なコードを書くことが可能ですが、従来のループを使用した方法も柔軟性があり、シンプルな処理には適しています。

これらの情報を参考にして、実際のプロジェクトで最適な方法を選択し、効果的にListを結合してみてください。

関連記事

Back to top button