モジュール java.base
パッケージ java.util.stream

インタフェースStream<T>

  • 型パラメータ:
    T - ストリーム要素の型
    すべてのスーパー・インタフェース:
    AutoCloseable, BaseStream<T,​Stream<T>>

    public interface Stream<T>
    extends BaseStream<T,​Stream<T>>
    順次および並列の集約操作をサポートする要素のシーケンスです。 次の例は、StreamIntStreamを使用する集計操作を示したものです。
    
         int sum = widgets.stream()
                          .filter(w -> w.getColor() == RED)
                          .mapToInt(w -> w.getWeight())
                          .sum();
     
    この例では、widgetsCollection<Widget>です。 Collection.stream()経由でWidgetオブジェクトのストリームが作成され、その結果がフィルタリングされて赤色のウィジェットのみを含むストリームが生成された後、それが、各赤色ウィジェットの重量を表すint値のストリームに変換されます。 続いてこのストリームが合計され、合計重量が生成されます。

    オブジェクト参照のストリームであるStreamのほかに、IntStreamLongStreamおよびDoubleStream用のプリミティブ特殊化も存在しており、これらもすべてストリームと呼ばれ、ここで記述する特性や制限に準拠します。

    計算を実行できるように、複数のストリーム操作を組み合わせて1つのストリーム・パイプラインが形成されます。 ストリーム・パイプラインは、1つのソース(配列、コレクション、ジェネレータ関数、入出力チャネルなど)、0個以上の中間操作(filter(Predicate)など、あるストリームを別のストリームに変換する操作)および1つの終端操作(count()forEach(Consumer)など、結果または副作用を生成する操作)から構成されます。 ストリームは遅延処理されます。ソース・データに対する計算は終端操作が起動されるまで実行されず、ソース要素も必要なだけしか消費されません。

    ストリームの実装には、結果の計算を最適化する際に重要な緯度が許可されます。 例えば、ストリームの実装はストリーム・パイプラインから(または全ステージ)オペレーションを削除することが自由です-- したがって、行動パラメータの呼び出しを無効にします-- それが計算の結果に影響しないことが証明できれば。 これは、行動パラメータの副作用が必ずしも実行されるとは限らないことを意味し、特に指定されない限り、依存するべきではないことを意味します。(端末操作forEachおよびforEachOrderedなどによる)。 (このような最適化の具体例については、count()操作で説明されているAPIノートを参照してください。 詳細については、ストリーム・パッケージのドキュメントのside-effectsセクションを参照してください。)

    コレクションとストリームは、表面上似た点があるものの、異なる目的を持っています。 コレクションは主に、要素の効率的な管理やアクセスに注力しています。 これに対し、ストリームは要素の直接アクセスや操作の手段を持たず、代わりにソースやそのソースに対して集約的に実行される計算操作を宣言的に記述することに注力しています。 ただし、用意されたストリーム操作が必要な機能を提供しない場合には、BaseStream.iterator()およびBaseStream.spliterator()操作を使って制御されたトラバーサルを実行することもできます。

    ストリーム・パイプラインは、上の「widgets」の例のように、ストリーム・ソースに対する問合せとみなすことができます。 ソースが明示的に同時変更向けに設計されたもの(ConcurrentHashMapなど)でないかぎり、ストリームのソースを照会中に変更すると、予測不可能な動作や間違った動作が発生する可能性があります。

    ほとんどのストリーム操作は、上の例でmapToIntに渡されたラムダ式w -> w.getWeight()のような、ユーザー指定の動作を記述するパラメータを受け取ります。 正しい動作を維持するには、これらの動作パラメータは次を満たす必要があります。

    • 非干渉でなければいけない(ストリームのソースを変更しない)、および
    • ほとんどの場合、ステートレスでなければいけない(その結果は、ストリーム・パイプラインの実行中に変化する可能性のあるどの状態にも依存すべきでない)。

    そのようなパラメータは常に関数型インタフェース(Functionなど)のインスタンスであり、通常はラムダ式やメソッド参照になります。 特に明記されていないかぎり、これらのパラメータはnull以外でなければいけません。

    (中間または終端ストリーム操作を呼び出して)ストリームを操作するのは、一度だけにすべきです。 このため、たとえば同じソースが2つ以上のパイプラインに対してデータを供給する「フォークされた」ストリームや、同じストリームを複数回トラバースすることなどは、禁止されます。 ストリーム実装は、ストリームが再利用されているのを検出すると、IllegalStateExceptionをスローします。 ただし、一部のストリーム操作からは新しいストリーム・オブジェクトではなくレシーバが返されることがあるため、場合によっては再利用を検出できない可能性があります。

    ストリームはBaseStream.close()メソッドを持ち、AutoCloseableを実装します。 ストリームが閉じられた後でストリームを操作すると、IllegalStateExceptionがスローされます。 ほとんどのストリーム・インスタンスは、特別なリソース管理を必要としないコレクション、配列、または生成関数によってサポートされているため、実際には使用後に閉じる必要はありません。 一般的に、Files.lines(Path)によって返されるものなど、IOチャネルであるストリームを持つストリームのみがクローズする必要があります。 ストリームが終了する必要がある場合は、try-with-resources文または同様の制御構造内のリソースとしてオープンして、操作が完了した後すぐに閉じられるようにする必要があります。

    ストリーム・パイプラインは順次、並列のいずれかで実行できます。 この実行モードは、ストリームのプロパティの1つです。 ストリームの作成時には、順次実行または並列実行の初期選択が行われます。 (たとえば、Collection.stream()では順次ストリームが作成され、Collection.parallelStream()では並列ストリームが作成されます。) この実行モードの選択を変更するにはBaseStream.sequential()またはBaseStream.parallel()メソッドを使用し、実行モードを照会するにはBaseStream.isParallel()メソッドを使用します。

    導入されたバージョン:
    1.8
    関連項目:
    IntStream, LongStream, DoubleStream, java.util.stream
    • ネストされたクラスのサマリー

      ネストされたクラス 
      修飾子と型 インタフェース 説明
      static interface  Stream.Builder<T>
      Streamの可変ビルダーです。
    • メソッドのサマリー

      すべてのメソッド staticメソッド インスタンス・メソッド 抽象メソッド デフォルト・メソッド 
      修飾子と型 メソッド 説明
      boolean allMatch​(Predicate<? super T> predicate)
      このストリームのすべての要素が指定された述語に一致するかどうかを返します。
      boolean anyMatch​(Predicate<? super T> predicate)
      このストリームのいずれかの要素が指定された述語に一致するかどうかを返します。
      static <T> Stream.Builder<T> builder()
      Streamのビルダーを返します。
      <R> R collect​(Supplier<R> supplier, BiConsumer<R,​? super T> accumulator, BiConsumer<R,​R> combiner)
      このストリームの要素に対して可変リダクション操作を実行します。
      <R,​A>
      R
      collect​(Collector<? super T,​A,​R> collector)
      Collectorを使ってこのストリームの要素に対する可変リダクション操作を実行します。
      static <T> Stream<T> concat​(Stream<? extends T> a, Stream<? extends T> b)
      最初のストリームの全要素と2番目のストリームの全要素を連結したものを要素に持つ、遅延連結ストリームを作成します。
      long count()
      このストリームの要素の個数を返します。
      Stream<T> distinct()
      このストリームの重複を除いた要素(Object.equals(Object)による)から構成されるストリームを返します。
      default Stream<T> dropWhile​(Predicate<? super T> predicate)
      このストリームが順序付けされている場合は、指定された述語に一致する要素の最長プレフィクスを削除した後に、このストリームの残りの要素で構成されるストリームを返します。
      static <T> Stream<T> empty()
      空の順次Streamを返します。
      Stream<T> filter​(Predicate<? super T> predicate)
      このストリームの要素のうち、指定された述語に一致するものから構成されるストリームを返します。
      Optional<T> findAny()
      ストリームの一部の要素を記述するOptionalを返します。ストリームが空の場合は空のOptionalを返します。
      Optional<T> findFirst()
      このストリームの最初の要素を記述するOptionalを返します。ストリームが空の場合は空のOptionalを返します。
      <R> Stream<R> flatMap​(Function<? super T,​? extends Stream<? extends R>> mapper)
      このストリームの各要素をマップされたストリーム(指定されたマッピング関数を各要素に適用することで得られる)の内容で置き換えた結果から成るストリームを返します。
      DoubleStream flatMapToDouble​(Function<? super T,​? extends DoubleStream> mapper)
      このストリームの各要素を、その要素に指定されたマッピング関数を適用することによって生成されるマップ先ストリームの内容で置き換えた結果から構成されるDoubleStreamを返します。
      IntStream flatMapToInt​(Function<? super T,​? extends IntStream> mapper)
      このストリームの各要素をマップされたストリーム(指定されたマッピング関数を各要素に適用することで得られる)の内容で置き換えた結果から成るIntStreamを返します。
      LongStream flatMapToLong​(Function<? super T,​? extends LongStream> mapper)
      このストリームの各要素をマップされたストリーム(指定されたマッピング関数を各要素に適用することで得られる)の内容で置き換えた結果から成るLongStreamを返します。
      void forEach​(Consumer<? super T> action)
      このストリームの各要素に対してアクションを実行します。
      void forEachOrdered​(Consumer<? super T> action)
      このストリームの各要素に対してアクションを実行します。その実行順は、ストリームの検出順が定義されている場合はその順番になります。
      static <T> Stream<T> generate​(Supplier<? extends T> s)
      指定されたSupplierによって生成される要素を含む、順序付けされていない無限順次ストリームを返します。
      static <T> Stream<T> iterate​(T seed, Predicate<? super T> hasNext, UnaryOperator<T> next)
      指定されたnext関数を初期要素に反復適用することによって生成され、与えられたhasNext述語を満たすことを条件とする、順次順序付けされたStreamを返します。
      static <T> Stream<T> iterate​(T seed, UnaryOperator<T> f)
      初期要素seedに関数fを繰り返し適用することで生成される、順序付けされた無限順次Streamを返します(seedf(seed)f(f(seed))、といった要素から成るStreamが生成される)。
      Stream<T> limit​(long maxSize)
      このストリームの要素をmaxSize以内の長さに切り詰めた結果から成るストリームを返します。
      <R> Stream<R> map​(Function<? super T,​? extends R> mapper)
      このストリームの要素に指定された関数を適用した結果から構成されるストリームを返します。
      DoubleStream mapToDouble​(ToDoubleFunction<? super T> mapper)
      このストリームの要素に指定された関数を適用した結果から構成されるDoubleStreamを返します。
      IntStream mapToInt​(ToIntFunction<? super T> mapper)
      このストリームの要素に指定された関数を適用した結果から構成されるIntStreamを返します。
      LongStream mapToLong​(ToLongFunction<? super T> mapper)
      このストリームの要素に指定された関数を適用した結果から構成されるLongStreamを返します。
      Optional<T> max​(Comparator<? super T> comparator)
      指定されたComparatorに従ってこのストリームの最大要素を返します。
      Optional<T> min​(Comparator<? super T> comparator)
      指定されたComparatorに従ってこのストリームの最小要素を返します。
      boolean noneMatch​(Predicate<? super T> predicate)
      指定された述語に一致する要素がこのストリーム内に存在しないかどうかを返します。
      static <T> Stream<T> of​(T t)
      単一要素を含む順次Streamを返します。
      static <T> Stream<T> of​(T... values)
      指定された値を要素に持つ、順序付けされた順次ストリームを返します。
      static <T> Stream<T> ofNullable​(T t)
      非nullならば、単一の要素を含むシーケンシャルなStreamを返します。それ以外の場合は空のStreamを返します。
      Stream<T> peek​(Consumer<? super T> action)
      このストリームの要素から成るストリームを返すほか、その結果のストリームから消費される各要素に対し、指定されたアクションを実行します。
      Optional<T> reduce​(BinaryOperator<T> accumulator)
      結合的累積関数を使用して、このストリームの要素に対してリダクションを実行し、リダクションされた値を記述するOptionalを返します(ある場合)。
      T reduce​(T identity, BinaryOperator<T> accumulator)
      指定された単位元の値と結合的な累積関数を使ってこのストリームの要素に対してリダクションを実行し、リデュースされた値を返します。
      <U> U reduce​(U identity, BiFunction<U,​? super T,​U> accumulator, BinaryOperator<U> combiner)
      指定された単位元、累積関数、および結合的関数を使用して、このストリームの要素に対してリダクションを実行します。
      Stream<T> skip​(long n)
      このストリームの最初のn個の要素を破棄した残りの要素で構成されるストリームを返します。
      Stream<T> sorted()
      このストリームの要素を自然順序に従ってソートした結果から構成されるストリームを返します。
      Stream<T> sorted​(Comparator<? super T> comparator)
      このストリームの要素で構成されるストリームを、指定されたComparatorに従ってソートして返します。
      default Stream<T> takeWhile​(Predicate<? super T> predicate)
      このストリームが順序付けされている場合、指定された述語に一致するこのストリームから取得された要素の最長プレフィクスからなるストリームを返します。
      Object[] toArray()
      このストリームの要素を含む配列を返します。
      <A> A[] toArray​(IntFunction<A[]> generator)
      指定されたgenerator関数を使用して、このストリームの要素を含む配列を返し、返された配列と、パーティション化された実行またはサイズ変更に必要となる可能性のある追加の配列を割り当てます。
    • メソッドの詳細

      • filter

        Stream<T> filter​(Predicate<? super T> predicate)
        このストリームの要素のうち、指定された述語に一致するものから構成されるストリームを返します。

        これは中間操作です。

        パラメータ:
        predicate - 各要素を含めるべきか判定する目的で各要素に適用する、非干渉ステートレスな述語
        戻り値:
        新しいストリーム
      • map

        <R> Stream<R> map​(Function<? super T,​? extends R> mapper)
        このストリームの要素に指定された関数を適用した結果から構成されるストリームを返します。

        これは中間操作です。

        型パラメータ:
        R - 新しいストリームの要素の型
        パラメータ:
        mapper - 各要素に適用する非干渉ステートレスな関数
        戻り値:
        新しいストリーム
      • mapToInt

        IntStream mapToInt​(ToIntFunction<? super T> mapper)
        このストリームの要素に指定された関数を適用した結果から構成されるIntStreamを返します。

        これは中間操作です。

        パラメータ:
        mapper - 各要素に適用する非干渉ステートレスな関数
        戻り値:
        新しいストリーム
      • mapToLong

        LongStream mapToLong​(ToLongFunction<? super T> mapper)
        このストリームの要素に指定された関数を適用した結果から構成されるLongStreamを返します。

        これは中間操作です。

        パラメータ:
        mapper - 各要素に適用する非干渉ステートレスな関数
        戻り値:
        新しいストリーム
      • mapToDouble

        DoubleStream mapToDouble​(ToDoubleFunction<? super T> mapper)
        このストリームの要素に指定された関数を適用した結果から構成されるDoubleStreamを返します。

        これは中間操作です。

        パラメータ:
        mapper - 各要素に適用する非干渉ステートレスな関数
        戻り値:
        新しいストリーム
      • flatMap

        <R> Stream<R> flatMap​(Function<? super T,​? extends Stream<? extends R>> mapper)
        このストリームの各要素をマップされたストリーム(指定されたマッピング関数を各要素に適用することで得られる)の内容で置き換えた結果から成るストリームを返します。 各マップ先ストリームは、その内容がこのストリーム内に配置されるとクローズされます。 (マップ先ストリームがnullの場合はかわりに空のストリームが使用されます。)

        これは中間操作です。

        APIのノート:
        flatMap()操作には、ストリームの要素に対して1対多の変換を適用した後、結果の要素を新しいストリーム内にフラット化する効果があります。

        ordersが購入注文のストリームであり、各購入注文には明細行のコレクションが含まれている場合、次のようにすると、すべての注文のすべての明細行を含むストリームが生成されます。

        
             orders.flatMap(order -> order.getLineItems().stream())...
         

        pathがファイルへのパスである場合、次のようにすると、そのファイルに含まれる単語のストリームが生成されます。

        
             Stream<String> lines = Files.lines(path, StandardCharsets.UTF_8);
             Stream<String> words = lines.flatMap(line -> Stream.of(line.split(" +")));
         
        flatMapに渡されたmapper関数は、単純な正規表現を使って1行を単語の配列に分割した後、その配列から単語のストリームを作成します。

        型パラメータ:
        R - 新しいストリームの要素の型
        パラメータ:
        mapper - 新しい値のストリームを生成するために各要素に適用する、非干渉ステートレスな関数
        戻り値:
        新しいストリーム
      • flatMapToInt

        IntStream flatMapToInt​(Function<? super T,​? extends IntStream> mapper)
        このストリームの各要素をマップされたストリーム(指定されたマッピング関数を各要素に適用することで得られる)の内容で置き換えた結果から成るIntStreamを返します。 各マップ先ストリームは、その内容がこのストリーム内に配置されるとクローズされます。 (マップ先ストリームがnullの場合はかわりに空のストリームが使用されます。)

        これは中間操作です。

        パラメータ:
        mapper - 新しい値のストリームを生成するために各要素に適用する、非干渉ステートレスな関数
        戻り値:
        新しいストリーム
        関連項目:
        flatMap(Function)
      • flatMapToLong

        LongStream flatMapToLong​(Function<? super T,​? extends LongStream> mapper)
        このストリームの各要素をマップされたストリーム(指定されたマッピング関数を各要素に適用することで得られる)の内容で置き換えた結果から成るLongStreamを返します。 各マップ先ストリームは、その内容がこのストリーム内に配置されるとクローズされます。 (マップ先ストリームがnullの場合はかわりに空のストリームが使用されます。)

        これは中間操作です。

        パラメータ:
        mapper - 新しい値のストリームを生成するために各要素に適用する、非干渉ステートレスな関数
        戻り値:
        新しいストリーム
        関連項目:
        flatMap(Function)
      • flatMapToDouble

        DoubleStream flatMapToDouble​(Function<? super T,​? extends DoubleStream> mapper)
        このストリームの各要素を、その要素に指定されたマッピング関数を適用することによって生成されるマップ先ストリームの内容で置き換えた結果から構成されるDoubleStreamを返します。 各マップ先ストリームは、その内容がこのストリーム内に配置されるとクローズされます。 (マップ先ストリームがnullの場合はかわりに空のストリームが使用されます。)

        これは中間操作です。

        パラメータ:
        mapper - 新しい値のストリームを生成するために各要素に適用する、非干渉ステートレスな関数
        戻り値:
        新しいストリーム
        関連項目:
        flatMap(Function)
      • distinct

        Stream<T> distinct()
        このストリームの重複を除いた要素(Object.equals(Object)による)から構成されるストリームを返します。

        順序付けされたストリームの場合、重複のない要素の選択は安定しています(重複した要素では、検出順で最初に現れた要素が維持されます。) 順序付けされていないストリームの場合、安定性は一切保証されません。

        これはステートフルな中間操作です。

        APIのノート:
        並列パイプラインでdistinct()の安定性を維持するコストは比較的高くなります(操作が完全なバリアーとして動作する必要があり、バッファリングのオーバーヘッドがかなり大きくなる)が、安定性が不要なこともよくあります。 状況のセマンティックスが許せば、順序付けされていないストリーム・ソース(generate(Supplier)など)を使用するか、BaseStream.unordered()で順序付けの制約をなくせば、並列パイプラインでのdistinct()の実行効率が大幅に向上する可能性があります。 検出順序との整合性が必要で、かつ並列パイプラインでのdistinct()のパフォーマンスやメモリー使用量に問題がある場合には、BaseStream.sequential()で順次実行に切り替えるとパフォーマンスが改善される可能性があります。
        戻り値:
        新しいストリーム
      • sorted

        Stream<T> sorted()
        このストリームの要素を自然順序に従ってソートした結果から構成されるストリームを返します。 このストリームの要素がComparableでない場合は、終端操作の実行時にjava.lang.ClassCastExceptionがスローされる可能性があります。

        順序付けされたストリームの場合、ソートは安定しています。 順序付けされていないストリームの場合、安定性は一切保証されません。

        これはステートフルな中間操作です。

        戻り値:
        新しいストリーム
      • sorted

        Stream<T> sorted​(Comparator<? super T> comparator)
        このストリームの要素で構成されるストリームを、指定されたComparatorに従ってソートして返します。

        順序付けされたストリームの場合、ソートは安定しています。 順序付けされていないストリームの場合、安定性は一切保証されません。

        これはステートフルな中間操作です。

        パラメータ:
        comparator - ストリーム要素の比較に使用される、非干渉ステートレスComparator
        戻り値:
        新しいストリーム
      • peek

        Stream<T> peek​(Consumer<? super T> action)
        このストリームの要素から成るストリームを返すほか、その結果のストリームから消費される各要素に対し、指定されたアクションを実行します。

        これは中間操作です。

        並列ストリーム・パイプラインの場合、上流の操作によって用意された各要素に対し、任意のタイミングで任意のスレッド内でアクションが呼び出される可能性があります。 アクションが共有状態を変更する場合、必要な同期を提供する責任はアクションにあります。

        APIのノート:
        このメソッドの主な存在理由は、要素がパイプライン内の特定のポイントを通過する際にその内容を確認するようなデバッグをサポートすることにあります。
        
             Stream.of("one", "two", "three", "four")
                 .filter(e -> e.length() > 3)
                 .peek(e -> System.out.println("Filtered value: " + e))
                 .map(String::toUpperCase)
                 .peek(e -> System.out.println("Mapped value: " + e))
                 .collect(Collectors.toList());
         

        ストリーム実装が要素(findFirstのような短絡操作やcount()に記載されている例)の一部またはすべての生成を最適化できる場合、その要素に対してアクションは呼び出されません。

        パラメータ:
        action - ストリームから消費される要素に対して実行すべき非干渉アクション
        戻り値:
        新しいストリーム
      • limit

        Stream<T> limit​(long maxSize)
        このストリームの要素をmaxSize以内の長さに切り詰めた結果から成るストリームを返します。

        これは、ステートフルな短絡中間操作です。

        APIのノート:
        limit()は、順次ストリーム・パイプラインでは一般に低コストの操作ですが、順序付けされた並列パイプラインではコストが非常に高くなる可能性があります(特にmaxSizeの値が大きい場合)。任意のn個の要素を返すだけでなく、検出順での最初のn個の要素を返さなければいけない、という制約がlimit(n)に課されるからです。 状況のセマンティックスが許せば、順序付けされていないストリーム・ソース(generate(Supplier)など)を使用するか、BaseStream.unordered()で順序付けの制約をなくせば、並列パイプラインのlimit()が大幅に高速化される可能性があります。 検出順序との整合性が必要で、かつ並列パイプラインでのlimit()のパフォーマンスやメモリー使用量に問題がある場合には、BaseStream.sequential()で順次実行に切り替えるとパフォーマンスが改善される可能性があります。
        パラメータ:
        maxSize - ストリームの要素数の上限
        戻り値:
        新しいストリーム
        例外:
        IllegalArgumentException - maxSizeが負の場合
      • skip

        Stream<T> skip​(long n)
        このストリームの最初のn個の要素を破棄した残りの要素で構成されるストリームを返します。 このストリームに含まれる要素の数がn個より少ない場合は、空のストリームが返されます。

        これはステートフルな中間操作です。

        APIのノート:
        skip()は、順次ストリーム・パイプラインでは一般に低コストの操作ですが、順序付けされた並列パイプラインではコストが非常に高くなる可能性があります(特にnの値が大きい場合)。任意のn個の要素をスキップするだけでなく、検出順での最初のn個の要素をスキップしなければいけない、という制約がskip(n)に課されるからです。 状況のセマンティックスが許せば、順序付けされていないストリーム・ソース(generate(Supplier)など)を使用するか、BaseStream.unordered()で順序付けの制約をなくせば、並列パイプラインのskip()が大幅に高速化される可能性があります。 検出順序との整合性が必要で、かつ並列パイプラインでのskip()のパフォーマンスやメモリー使用量に問題がある場合には、BaseStream.sequential()で順次実行に切り替えるとパフォーマンスが改善される可能性があります。
        パラメータ:
        n - スキップする先頭要素の数
        戻り値:
        新しいストリーム
        例外:
        IllegalArgumentException - nが負の場合
      • takeWhile

        default Stream<T> takeWhile​(Predicate<? super T> predicate)
        このストリームが順序付けされている場合、指定された述語に一致するこのストリームから取得された要素の最長プレフィクスからなるストリームを返します。 そうでない場合は、このストリームが順序付けられていない場合、指定された述語に一致するこのストリームから取り出された要素のサブセットからなるストリームを返します。

        このストリームが順序付けされている場合、最長のプレフィクスは、指定された述語に一致するこのストリームの要素の連続したシーケンスです。 シーケンスの最初の要素はこのストリームの最初の要素であり、シーケンスの最後の要素の直後の要素は指定された述語と一致しません。

        このストリームが順序付けされておらず、このストリームの一部の(すべてではない)要素が指定された述語と一致する場合、この操作の動作は非決定的です。一致する要素(空のセットを含む)のサブセットを自由に取ることができます。

        このストリームのすべての要素が指定された述語に一致する場合、このストリームが順序付けられているかどうかにかかわらず、この操作ではすべての要素(結果は入力と同じです)が使用され、ストリームの要素が指定された述語に一致しない場合は(結果は空のストリームです)は使用されません。

        これは、ステートフルな短絡中間操作です。

        APIのノート:
        takeWhile()は通常、シーケンシャル・ストリーム・パイプラインでは安価な操作ですが、順序付けされたパラレル・パイプラインでは非常に高価ですが、操作は有効なプレフィクスだけでなく、エンカウンタの順序で要素の最長プレフィクスを返すように制限されています。 並べ替えられていないストリーム・ソース(generate(Supplier)など)を使用するか、BaseStream.unordered()で順序付け制約を削除すると、状況のセマンティクスが許せば、並列パイプラインでtakeWhile()が大幅に高速化される可能性があります。 エンカウンタ・オーダーとの一貫性が必要で、並列パイプラインでtakeWhile()のパフォーマンスやメモリー使用率が低下している場合は、BaseStream.sequential()を使用して順次実行に切り替えるとパフォーマンスが向上する可能性があります。
        実装要件:
        デフォルトの実装では、このストリームのspliteratorを取得し、そのスプライテータをラップしてこの操作のセマンティクスをトラバースでサポートし、ラップされたスプライテータに関連付けられた新しいストリームを返します。 返されたストリームはこのストリーム(BaseStream.isParallel()による並列実行または順次実行)の実行特性を保持しますが、ラップされたスプライテータは分割をサポートしないことを選択することがあります。 返されたストリームが閉じられると、返されたストリームとこのストリームのクローズ・ハンドラが呼び出されます。
        パラメータ:
        predicate - non-interferingstateless述語は、要素の最長プレフィクスを決定する要素に適用されます。
        戻り値:
        新しいストリーム
        導入されたバージョン:
        9
      • dropWhile

        default Stream<T> dropWhile​(Predicate<? super T> predicate)
        このストリームが順序付けされている場合は、指定された述語に一致する要素の最長プレフィクスを削除した後に、このストリームの残りの要素で構成されるストリームを返します。 そうでない場合は、このストリームが順序付けられていない場合は、指定された述語に一致する要素のサブセットを削除した後、このストリームの残りの要素からなるストリームを返します。

        このストリームが順序付けされている場合、最長のプレフィクスは、指定された述語に一致するこのストリームの要素の連続したシーケンスです。 シーケンスの最初の要素はこのストリームの最初の要素であり、シーケンスの最後の要素の直後の要素は指定された述語と一致しません。

        このストリームが順序付けされておらず、このストリームの一部の(すべてではない)要素が指定された述語と一致する場合、この操作の動作は非決定的です。一致する要素(空のセットを含む)のサブセットを自由に削除することができます。

        このストリームのすべての要素が指定された述語と一致する場合、このストリームが順序付けされているかどうかに関係なく、この操作ではすべての要素(結果は空のストリームです)が削除されるか、またはストリームの要素が指定された述語に一致しない場合、要素は削除されません(結果は入力と同じです)。

        これはステートフルな中間操作です。

        APIのノート:
        dropWhile()は通常、シーケンシャル・ストリーム・パイプラインでは安価な操作ですが、順序付けされたパラレル・パイプラインでは非常に高価ですが、操作は有効なプレフィクスだけでなく、エンカウンタの順序で要素の最長プレフィクスを返すように制限されています。 並べ替えられていないストリーム・ソース(generate(Supplier)など)を使用するか、BaseStream.unordered()で順序付け制約を削除すると、状況のセマンティクスが許せば、並列パイプラインでdropWhile()が大幅に高速化される可能性があります。 エンカウンタ・オーダーとの一貫性が必要で、並列パイプラインでdropWhile()のパフォーマンスやメモリー使用率が低下している場合は、BaseStream.sequential()を使用して順次実行に切り替えるとパフォーマンスが向上する可能性があります。
        実装要件:
        デフォルトの実装では、このストリームのspliteratorを取得し、そのスプライテータをラップしてこの操作のセマンティクスをトラバースでサポートし、ラップされたスプライテータに関連付けられた新しいストリームを返します。 返されたストリームはこのストリーム(BaseStream.isParallel()による並列実行または順次実行)の実行特性を保持しますが、ラップされたスプライテータは分割をサポートしないことを選択することがあります。 返されたストリームが閉じられると、返されたストリームとこのストリームのクローズ・ハンドラが呼び出されます。
        パラメータ:
        predicate - non-interferingstateless述語は、要素の最長プレフィクスを決定する要素に適用されます。
        戻り値:
        新しいストリーム
        導入されたバージョン:
        9
      • forEach

        void forEach​(Consumer<? super T> action)
        このストリームの各要素に対してアクションを実行します。

        これは終端操作です。

        この操作の動作は明らかに非決定論的です。 並列ストリーム・パイプラインの場合、この操作は、ストリームの検出順序を考慮することを保証しません。保証すると並列性のメリットが犠牲になるからです。 与えられた任意の要素に対し、ライブラリが選択した任意のタイミングで任意のスレッド内でアクションが実行される可能性があります。 アクションが共有状態にアクセスする場合、必要な同期を提供する責任はアクションにあります。

        パラメータ:
        action - 要素に対して実行する非干渉アクション
      • forEachOrdered

        void forEachOrdered​(Consumer<? super T> action)
        このストリームの各要素に対してアクションを実行します。その実行順は、ストリームの検出順が定義されている場合はその順番になります。

        これは終端操作です。

        この操作は、検出順序が存在する場合はその順序で、要素を一度に1つずつ処理します。 ある要素のアクション実行はその後続要素のアクション実行よりも前に発生しますが、どの要素についても、ライブラリが選択した任意のスレッド内でアクションが実行される可能性があります。

        パラメータ:
        action - 要素に対して実行する非干渉アクション
        関連項目:
        forEach(Consumer)
      • toArray

        <A> A[] toArray​(IntFunction<A[]> generator)
        指定されたgenerator関数を使用して、このストリームの要素を含む配列を返し、返された配列と、パーティション化された実行またはサイズ変更に必要となる可能性のある追加の配列を割り当てます。

        これは終端操作です。

        APIのノート:
        ジェネレータ関数は、要求された配列のサイズを表す整数を受け取り、要求されたサイズの配列を生成します。 これは、配列コンストラクタ参照で簡潔に表現できます。
        
             Person[] men = people.stream()
                                  .filter(p -> p.getGender() == MALE)
                                  .toArray(Person[]::new);
         
        型パラメータ:
        A - 結果の配列のコンポーネント型
        パラメータ:
        generator - 要求された型と指定された長さを持つ新しい配列を生成する関数
        戻り値:
        このストリームの要素を含む配列
        例外:
        ArrayStoreException - このストリームの要素の実行時の型が、生成された配列の「ランタイム・コンポーネント・タイプ」に代入可能でない場合
      • reduce

        T reduce​(T identity,
                 BinaryOperator<T> accumulator)
        指定された単位元の値と結合的な累積関数を使ってこのストリームの要素に対してリダクションを実行し、リデュースされた値を返します。 これは、次の操作に相当します。
        
             T result = identity;
             for (T element : this stream)
                 result = accumulator.apply(result, element)
             return result;
         
        ただし、順次実行の制約が課されるわけではありません。

        identity値はアキュムレータ関数の単位元でなければいけません。 つまり、すべてのtについて、accumulator.apply(identity, t)tに等しくなります。 アキュムレータ関数は結合的な関数でなければいけません。

        これは終端操作です。

        APIのノート:
        合計、最小、最大、平均、文字列連結はすべて、リダクションの特殊な場合です。 数値ストリームの合計は次のように表現できます。
        
             Integer sum = integers.reduce(0, (a, b) -> a+b);
         
        または
        
             Integer sum = integers.reduce(0, Integer::sum);
         

        これは、単純にループで中間合計を更新していく方法に比べて遠回りな集計方法に見えるかもしれませんが、リダクション操作の並列化が容易に行え、並列化の際に同期を追加する必要がなく、データ競合のリスクも大幅に減少します。

        パラメータ:
        identity - 蓄積関数に対する単位元の値
        accumulator - 2つの値を結合するための結合的非干渉、およびステートレスな関数
        戻り値:
        リダクションの結果
      • reduce

        Optional<T> reduce​(BinaryOperator<T> accumulator)
        結合的累積関数を使用して、このストリームの要素に対してリダクションを実行し、リダクションされた値を記述するOptionalを返します(ある場合)。 これは、次の操作に相当します。
        
             boolean foundAny = false;
             T result = null;
             for (T element : this stream) {
                 if (!foundAny) {
                     foundAny = true;
                     result = element;
                 }
                 else
                     result = accumulator.apply(result, element);
             }
             return foundAny ? Optional.of(result) : Optional.empty();
         
        ただし、順次実行の制約が課されるわけではありません。

        アキュムレータ関数は結合的な関数でなければいけません。

        これは終端操作です。

        パラメータ:
        accumulator - 2つの値を結合するための結合的非干渉、およびステートレスな関数
        戻り値:
        リダクションの結果を記述するOptional
        例外:
        NullPointerException - リダクションの結果がnullの場合
        関連項目:
        reduce(Object, BinaryOperator), min(Comparator), max(Comparator)
      • reduce

        <U> U reduce​(U identity,
                     BiFunction<U,​? super T,​U> accumulator,
                     BinaryOperator<U> combiner)
        指定された単位元、累積関数、および結合的関数を使用して、このストリームの要素に対してリダクションを実行します。 これは、次の操作に相当します。
        
             U result = identity;
             for (T element : this stream)
                 result = accumulator.apply(result, element)
             return result;
         
        ただし、順次実行の制約が課されるわけではありません。

        identity値はコンバイナ関数の単位元でなければいけません。 つまり、すべてのuについて、combiner(identity, u)uに等しくなります。 さらに、combiner関数はaccumulator関数と互換性がある必要があります。すべてのutについて、次が成り立つ必要があります。

        
             combiner.apply(u, accumulator.apply(identity, t)) == accumulator.apply(u, t)
         

        これは終端操作です。

        APIのノート:
        この形式を使用するリダクションの多くは、map操作とreduce操作を明示的に組み合わせることで、より単純に表現することができます。 accumulator関数はマッパーとアキュムレータを融合したものとして動作しますが、これは、以前のリデュース値がわかっていれば一部の計算を回避できる場合など、マッピングとリダクションを個別に実行するよりも効率的になる場合があります。
        型パラメータ:
        U - 結果の型
        パラメータ:
        identity - コンバイナ関数に対する単位元の値
        accumulator - 追加の要素を結果に組み込むための、結合的非干渉およびステートレスな関数
        combiner - 2つの値を結合するための結合的非干渉およびステートレスな関数(アキュムレータ関数と互換性がなければいけない)
        戻り値:
        リダクションの結果
        関連項目:
        reduce(BinaryOperator), reduce(Object, BinaryOperator)
      • collect

        <R> R collect​(Supplier<R> supplier,
                      BiConsumer<R,​? super T> accumulator,
                      BiConsumer<R,​R> combiner)
        このストリームの要素に対して可変リダクション操作を実行します。 可変リダクションとは、リデュース対象の値がArrayListのような可変の結果コンテナであり、結果を置き換えるかわりに結果の状態を更新することによって要素が組み込まれるようなリダクションのことです。 これは次と同等の結果を生成します。
        
             R result = supplier.get();
             for (T element : this stream)
                 accumulator.accept(result, element);
             return result;
         

        collect操作はreduce(Object, BinaryOperator)と同様、同期を追加しなくても並列化できます。

        これは終端操作です。

        APIのノート:
        JDKには、collect()の引数(メソッド参照)での使用に適したシグネチャを持つ既存クラスが多数存在しています。 たとえば次の場合、文字列がArrayList内に蓄積されます。
        
             List<String> asList = stringStream.collect(ArrayList::new, ArrayList::add,
                                                        ArrayList::addAll);
         

        次の場合、文字列のストリームが受け取られ、それらが連結されて単一の文字列になります。

        
             String concat = stringStream.collect(StringBuilder::new, StringBuilder::append,
                                                  StringBuilder::append)
                                         .toString();
         

        型パラメータ:
        R - 可変結果コンテナの型
        パラメータ:
        supplier - 新しい変更可能な結果コンテナを作成する関数。 並列実行の場合、この関数は複数回呼び出される可能性がありますが、そのたびに新しい値を返す必要があります。
        accumulator - associativenon-interferingstateless関数は、要素を結果コンテナに折りたたむ必要があります。
        combiner - associativenon-interferingstateless関数は、2つの部分結果コンテナを受け入れ、それらをマージします。これらのコンテナは、アキュムレータ関数と互換性がなければなりません。 コンバイナ関数は、第2の結果コンテナから第1の結果コンテナに要素を折りたたまなければなりません。
        戻り値:
        リダクションの結果
      • collect

        <R,​A> R collect​(Collector<? super T,​A,​R> collector)
        Collectorを使ってこのストリームの要素に対する可変リダクション操作を実行します。 collect(Supplier, BiConsumer, BiConsumer)の引数として使用される関数をカプセル化したCollectorを使えば、コレクション方針の再利用やcollect操作の合成(マルチレベルのグループ化や分割など)が可能となります。

        ストリームが並列的であり、Collector並行的であり、かつストリームが順序付けされていないかコレクタがunorderedである場合、並行リダクションが実行されます(並行リダクションの詳細はCollectorを参照。)

        これは終端操作です。

        並列実行時には、複数の中間結果のインスタンス化、データ設定、およびマージが可能であるため、可変データ構造の隔離を維持できます。 したがって、スレッドセーフでないデータ構造(ArrayListなど)で並列実行を行う場合でも、並列リダクション用の同期を追加する必要はありません。

        APIのノート:
        次の場合、文字列がArrayList内に蓄積されます。
        
             List<String> asList = stringStream.collect(Collectors.toList());
         

        次の場合、Personオブジェクトが市町村別に分類されます。

        
             Map<String, List<Person>> peopleByCity
                 = personStream.collect(Collectors.groupingBy(Person::getCity));
         

        次の場合、2つのCollectorをカスケード接続することにより、Personオブジェクトが都道府県別、市町村別に分類されます。

        
             Map<String, Map<String, List<Person>>> peopleByStateAndCity
                 = personStream.collect(Collectors.groupingBy(Person::getState,
                                                              Collectors.groupingBy(Person::getCity)));
         

        型パラメータ:
        R - 結果の型
        A - Collectorの中間蓄積の型
        パラメータ:
        collector - リダクションを記述するCollector
        戻り値:
        リダクションの結果
        関連項目:
        collect(Supplier, BiConsumer, BiConsumer), Collectors
      • min

        Optional<T> min​(Comparator<? super T> comparator)
        指定されたComparatorに従ってこのストリームの最小要素を返します。 これはリダクションの特殊な場合です。

        これは終端操作です。

        パラメータ:
        comparator - このストリームの要素を比較する、非干渉ステートレスComparator
        戻り値:
        このストリームの最小要素を記述するOptionalまたは空のOptional (ストリームが空の場合)
        例外:
        NullPointerException - 最小要素がnullの場合
      • max

        Optional<T> max​(Comparator<? super T> comparator)
        指定されたComparatorに従ってこのストリームの最大要素を返します。 これはリダクションの特殊な場合です。

        これは終端操作です。

        パラメータ:
        comparator - このストリームの要素を比較する、非干渉ステートレスComparator
        戻り値:
        このストリームの最大要素を記述するOptionalまたは空のOptional (ストリームが空の場合)
        例外:
        NullPointerException - 最大要素がnullの場合
      • count

        long count()
        このストリームの要素の個数を返します。 これはリダクションの特殊な場合であり、次と同等になります。
        
             return mapToLong(e -> 1L).sum();
         

        これは終端操作です。

        APIのノート:
        ストリーム・ソースから直接カウントを計算できる場合、実装はストリーム・パイプライン(連続的または並列的に)を実行しないことを選択することがあります。 このような場合、ソース要素はトラバースされず、中間演算は評価されません。 副作用を伴う動作パラメータは、デバッグなどの無害な場合を除いては、強く推奨されません。 たとえば、次のストリームを考えてみましょう:
        
             List<String> l = Arrays.asList("A", "B", "C", "D");
             long count = l.stream().peek(System.out::println).count();
         
        ストリーム・ソースによってカバーされる要素の数Listは既知であり、中間操作peekはストリーム(flatMapまたはfilter操作の場合のように)に要素を注入または削除しません。 したがって、カウントはListのサイズであり、パイプラインを実行する必要はなく、副作用としてリスト要素を出力します。
        戻り値:
        このストリームの要素の個数
      • anyMatch

        boolean anyMatch​(Predicate<? super T> predicate)
        このストリームのいずれかの要素が指定された述語に一致するかどうかを返します。 すべての要素で述語を評価するとは限りません(結果を決定するのに必要でない場合)。 ストリームが空の場合、falseが返され、述語は評価されません。

        これは短絡終端操作です。

        APIのノート:
        このメソッドは、ストリームの要素に対する述語の存在量化(あるxについてP(x))を評価します。
        パラメータ:
        predicate - ストリームの要素に適用する非干渉ステートレスな述語
        戻り値:
        指定された述語に一致する要素がストリーム内に存在する場合はtrue、そうでない場合はfalse
      • allMatch

        boolean allMatch​(Predicate<? super T> predicate)
        このストリームのすべての要素が指定された述語に一致するかどうかを返します。 すべての要素で述語を評価するとは限りません(結果を決定するのに必要でない場合)。 ストリームが空の場合、trueが返され、述語は評価されません。

        これは短絡終端操作です。

        APIのノート:
        このメソッドは、ストリームの要素に対する述語の全称量化(すべてのxについてP(x))を評価します。 ストリームが空の場合、量化は無意味に満たされると言い、(P(x)とは無関係に)常にtrueになります。
        パラメータ:
        predicate - ストリームの要素に適用する非干渉ステートレスな述語
        戻り値:
        ストリームのすべての要素が指定された述語に一致するかストリームが空の場合はtrue、それ以外の場合はfalse
      • noneMatch

        boolean noneMatch​(Predicate<? super T> predicate)
        指定された述語に一致する要素がこのストリーム内に存在しないかどうかを返します。 すべての要素で述語を評価するとは限りません(結果を決定するのに必要でない場合)。 ストリームが空の場合、trueが返され、述語は評価されません。

        これは短絡終端操作です。

        APIのノート:
        このメソッドは、ストリームの要素に対する述語の否定の全称量化(すべてのxについて~P(x))を評価します。 ストリームが空の場合、量化は無意味に満たされると言い、P(x)とは無関係に常にtrueになります。
        パラメータ:
        predicate - ストリームの要素に適用する非干渉ステートレスな述語
        戻り値:
        ストリームのどの要素も指定された述語に一致しないかストリームが空の場合はtrue、それ以外の場合はfalse
      • findFirst

        Optional<T> findFirst()
        このストリームの最初の要素を記述するOptionalを返します。ストリームが空の場合は空のOptionalを返します。 ストリームが検出順序を持たない場合は、任意の要素が返されます。

        これは短絡終端操作です。

        戻り値:
        このストリームの最初の要素を記述するOptionalまたは空のOptional (ストリームが空の場合)
        例外:
        NullPointerException - 選択された要素がnullの場合
      • findAny

        Optional<T> findAny()
        ストリームの一部の要素を記述するOptionalを返します。ストリームが空の場合は空のOptionalを返します。

        これは短絡終端操作です。

        この操作の動作は明らかに非決定論的です。ストリームの任意の要素を自由に選択できます。 これは、並列処理でのパフォーマンスを最大化できるようにするためです。デメリットは、同じソースに対して呼び出すたびに、違う結果が返される可能性がある点です。 (安定した結果が必要な場合は、かわりにfindFirst()を使用してください。)

        戻り値:
        このストリームのある要素を記述するOptionalまたは空のOptional (ストリームが空の場合)
        例外:
        NullPointerException - 選択された要素がnullの場合
        関連項目:
        findFirst()
      • builder

        static <T> Stream.Builder<T> builder()
        Streamのビルダーを返します。
        型パラメータ:
        T - 要素の型
        戻り値:
        ストリーム・ビルダー
      • empty

        static <T> Stream<T> empty()
        空の順次Streamを返します。
        型パラメータ:
        T - ストリーム要素の型
        戻り値:
        空の順次ストリーム
      • of

        static <T> Stream<T> of​(T t)
        単一要素を含む順次Streamを返します。
        型パラメータ:
        T - ストリーム要素の型
        パラメータ:
        t - 単一要素
        戻り値:
        単一要素の順次ストリーム
      • ofNullable

        static <T> Stream<T> ofNullable​(T t)
        非nullならば、単一の要素を含むシーケンシャルなStreamを返します。それ以外の場合は空のStreamを返します。
        型パラメータ:
        T - ストリーム要素の型
        パラメータ:
        t - 単一要素
        戻り値:
        指定された要素が非nullの場合は単一の要素を持つストリーム、そうでない場合は空のストリーム
        導入されたバージョン:
        9
      • of

        @SafeVarargs
        static <T> Stream<T> of​(T... values)
        指定された値を要素に持つ、順序付けされた順次ストリームを返します。
        型パラメータ:
        T - ストリーム要素の型
        パラメータ:
        values - 新しいストリームの要素
        戻り値:
        新しいストリーム
      • iterate

        static <T> Stream<T> iterate​(T seed,
                                     UnaryOperator<T> f)
        初期要素seedに関数fを繰り返し適用することで生成される、順序付けされた無限順次Streamを返します(seedf(seed)f(f(seed))、といった要素から成るStreamが生成される)。

        Streamの最初の要素(位置0)は、指定されたseedになります。 n > 0の場合、位置nの要素は、位置n - 1の要素に関数fを適用した結果になります。

        fを1つの要素に適用するアクションhappens-beforeは、後続の要素にfを適用するアクションです。 どのような要素に対しても、ライブラリが選択するどのスレッドでもアクションを実行できます。

        型パラメータ:
        T - ストリーム要素の型
        パラメータ:
        seed - 初期要素
        f - 新しい要素を生成するために前の要素に適用される関数
        戻り値:
        新しい順次Stream
      • iterate

        static <T> Stream<T> iterate​(T seed,
                                     Predicate<? super T> hasNext,
                                     UnaryOperator<T> next)
        指定されたnext関数を初期要素に反復適用することによって生成され、与えられたhasNext述語を満たすことを条件とする、順次順序付けされたStreamを返します。 ストリームは、hasNext述部がfalseを返すとすぐに終了します。

        Stream.iterateは、対応するforループによって生成されるものと同じシーケンスを生成する必要があります:

        
             for (T index=seed; hasNext.test(index); index = next.apply(index)) {
                 ...
             }
         

        hasNext述部がシード値を保持しない場合、結果のシーケンスは空になることがあります。 それ以外の場合、最初の要素は指定されたseed値になります。次の要素(存在する場合)は、next関数をseed値に適用した結果、hasNext述語がストリームを終了する必要があることを示すまで繰り返されます。

        hasNext述語を要素happens-beforeに適用するアクション。その要素にnext関数を適用するアクション。 1つの要素happens-beforenext関数を適用するアクション。後続の要素にhasNext述語を適用するアクション。 任意の要素に対して、ライブラリが選択したどのスレッドでもアクションを実行できます。

        型パラメータ:
        T - ストリーム要素の型
        パラメータ:
        seed - 初期要素
        hasNext - ストリームを終了する必要があるかどうかを判断する要素に適用する述語。
        next - 新しい要素を生成するために前の要素に適用される関数
        戻り値:
        新しい順次Stream
        導入されたバージョン:
        9
      • generate

        static <T> Stream<T> generate​(Supplier<? extends T> s)
        指定されたSupplierによって生成される要素を含む、順序付けされていない無限順次ストリームを返します。 これは、定数ストリームやランダムな要素から成るストリームなどを生成するのに適しています。
        型パラメータ:
        T - ストリーム要素の型
        パラメータ:
        s - 生成される要素のSupplier
        戻り値:
        順序付けされていない新しい無限順次Stream
      • concat

        static <T> Stream<T> concat​(Stream<? extends T> a,
                                    Stream<? extends T> b)
        最初のストリームの全要素と2番目のストリームの全要素を連結したものを要素に持つ、遅延連結ストリームを作成します。 結果のストリームが順序付けされるのは、入力ストリームがどちらも順序付けされている場合であり、並列的になるのは、入力ストリームのどちらかが並列的な場合です。 結果のストリームのクローズ時には、両方の入力ストリームのクローズ・ハンドラが呼び出されます。

        このメソッドは2つの入力ストリームで動作し、各ストリームをそのソースにバインドします。 その結果、入力ストリーム・ソースへのその後の変更は、連結ストリーム結果に反映されないことがあります。

        APIのノート:
        最適化の機会を保持するために、このメソッドは各ストリームをそのソースにバインドし、パラメータとして2つのストリームのみを受け入れます。 例えば、各入力ストリーム・ソースの正確なサイズが分かっている場合、連結ストリーム・ソースの正確なサイズを計算することができます。 バインディングなしでストリームを連結する場合、またはこのメソッドへのネストされた呼び出しを行わない場合は、ストリームのストリームを作成し、アイデンティティ関数を使用してフラット・マッピングしてみてください:
        
             Stream<T> concat = Stream.of(s1, s2, s3, s4).flatMap(s -> s);
         
        実装上のノート:
        連結を繰り返すことでストリームを構築する際には注意が必要です。 深く連結されたストリームの要素にアクセスすると、深い呼び出しチェーンやStackOverflowErrorが発生する可能性があります。

        返されたストリームのシーケンシャル/パラレル実行モードへのその後の変更は、入力ストリームに伝播することが保証されていません。

        型パラメータ:
        T - ストリーム要素の型
        パラメータ:
        a - 最初のストリーム
        b - 2番目のストリーム
        戻り値:
        2つの入力ストリームを連結したもの