public interface Stream<T> extends BaseStream<T,Stream<T>>
StreamとIntStreamを使った集計処理を示す。
int sum = widgets.stream()
.filter(w -> w.getColor() == RED)
.mapToInt(w -> w.getWeight())
.sum();
この例ではwidgetsはCollection<Widget>である。ここではWidgetオブジェクトのストリームをCollection.stream()で作成し、赤いウィジェットのみを含むストリームを作成するために絞り込み、それを赤い各ウィジェットの重さを表すintのストリームに変換する。そして重さの総計を求めるためにこのストリームの和が求められる。 オブジェクトへの参照のストリームであるStreamに加えて、プリミティブ値に特化したIntStream, LongStream, DoubleStreamもあり、これらは全てが「ストリーム」と呼ばれ、ここに示される全ての特性と制約を満たす。
計算を実行するために、ストリーム処理は組み立てられて1つのストリームパイプラインへと合成される。ストリームパイプラインは情報源(source、配列・コレクション・生成関数・I/Oチャンネルなど)、零個以上の中間処理(intermediate operations)(filter(Predicate)のようにストリームを別のストリームに変換する)、末端処理(terminal operation)(count()やforEach(Consumer)のように結果や副作用を生成する)からなる。ストリームは遅延的(lazy)である。つまり情報源のデータに対する計算は末端処理が開始された際にのみ実行され、情報源の要素は必要になったときに消費される。
コレクションとストリームは表面上の類似点はあるものの、異なる目的を持つ。コレクションはその要素の効率的な管理とその要素への効率的なアクセスに主に注意を注ぐ。対照的に、ストリームは要素へ直接アクセスする手段や要素を直接操作する手段を備えておらず、代わりに情報源と、情報源に対してまとめて実行される計算処理を宣言的に示すことに注意を注ぐ。ただし、用意されたストリーム演算に望む機能がない場合、走査の制御のためにBaseStream.iterator()演算とBaseStream.spliterator()演算が利用できる。
上記の「ウィジェット」の例のようなストリームパイプラインはストリーム源に対する問い合わせとして見ることもできる。情報源が(ConcurrentHashMapなどのように)並行的な変更のために特別に設計されている場合を除き、問い合わせ中にストリーム源を変更すると予測できない挙動や誤った挙動となる場合がある。
ほとんどのストリーム処理はユーザが指定する挙動を表わすパラメータを受け取る。上の例においてmapToIntに渡されるラムダ式w -> w.getWeight()などである。正しい動作を保つため、それらの挙動パラメータ(behavioral parameters)は次の条件を満たす必要がある。
このようなパラメータは常に関数的インターフェース(functional interface)のインスタンスであり、多くの場合ラムダ式やメソッド参照である。特に別記されてない限り、それらのパラメータはnullではいけない。
ストリームは一度だけ利用する(中間処理や末端処理を呼び出す)べきである。これは例えば「分岐」したストリームを認めない、つまり同じ情報源から複数のパイプラインに要素を供給したり、同じストリームを複数回走査するといったことを認めないということである。ストリームの実装はストリームが再利用されているのを検知した場合、IllegalStateExceptionを投げる場合がある。しかし、ある種のストリーム演算は新しいストリームオブジェクトではなくレシーバを返すため、再利用を常に検知できるとは限らない。
ストリームはBaseStream.close()メソッドを持ち、AutoCloseableを実装するが、ほとんど全てのストリームのインスタンスは実際には利用後に閉じる必要はない。一般的に、情報源がI/Oチャンネルであるようなストリーム(Files.lines(Path, Charset)が返すストリームなど)のみ閉じる必要がある。ほとんどのストリームはコレクション・配列・生成関数が元になっており、特別な資源管理を必要としない(もしストリームを閉じる必要がある場合、try-with-resources文の資源として宣言できる)。
ストリームパイプラインは逐次的に実行される場合と並列に実行される場合がある。この実行モードはストリームの特性である。ストリームは逐次実行か並列実行か選択されて作成される(例えば、Collection.stream()は逐次ストリームを作成し、Collection.parallelStream()は並列ストリームを作成する)。この実行モードの選択はBaseStream.sequential()メソッドやBaseStream.parallel()メソッドで変更でき、BaseStream.isParallel()メソッドで調べられる。
| 修飾子とタイプ | インタフェースと説明 |
|---|---|
static interface |
Stream.Builder<T>
Streamの可変なビルダこれにより要素を個別に生成してStreamBuilderへ追加して(ArrayListを一時バッファとして使った場合の複製のオーバーヘッド無しに)Streamを作成できるようになる。 |
| 修飾子とタイプ | メソッドと説明 |
|---|---|
boolean |
allMatch(Predicate<? super T> predicate)
このストリームの全ての要素が与えられた述語に適合するか返す。
|
boolean |
anyMatch(Predicate<? super T> predicate)
このストリームのある要素が与えられた述語に適合するか返す。
|
static <T> Stream.Builder<T> |
builder()
Streamのビルダを返す。 |
<R,A> R |
collect(Collector<? super T,A,R> collector)
Collectorを使ってこのストリームの要素に可変的簡約を実行する。 |
<R> R |
collect(Supplier<R> supplier,
BiConsumer<R,? super T> accumulator,
BiConsumer<R,R> combiner)
このストリームの要素に可変的簡約を実行する。
|
static <T> Stream<T> |
concat(Stream<? extends T> a,
Stream<? extends T> b)
ストリームの要素が、最初のストリームの全ての要素の後に2つ目のストリームの全ての要素を並べたような、遅延的に連結されたストリームを返す。
|
long |
count()
このストリームの要素数を返す。
|
Stream<T> |
distinct()
このストリームの要素のうち(
Object.equals(Object)に従って)重複を除いた要素からなるストリームを返す。 |
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<T> s)
各要素が
Supplierによって生成される、逐次的な無限Streamを返す。 |
static <T> Stream<T> |
iterate(T seed,
UnaryOperator<T> f)
初期要素
seedに対する関数fの繰り返しの適用によって生成された無限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... values)
要素が指定された値であるような逐次的なストリームを返す。
|
static <T> Stream<T> |
of(T t)
1つの要素を含む逐次的な
Streamを返す。 |
Stream<T> |
peek(Consumer<? super T> action)
このストリームの要素からなり、加えて結果のストリームから要素が消費されるごとにその要素にアクションを実行するストリームを返す。
|
Optional<T> |
reduce(BinaryOperator<T> accumulator)
|
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に従って整列した結果からなるストリームを返す。 |
Object[] |
toArray()
このストリームの要素からなる配列を返す。
|
<A> A[] |
toArray(IntFunction<A[]> generator)
このストリームの要素からなる配列を返す。
|
close, isParallel, iterator, onClose, parallel, sequential, spliterator, unorderedStream<T> filter(Predicate<? super T> predicate)
これは中間処理である。
<R> Stream<R> map(Function<? super T,? extends R> mapper)
これは中間処理である。
IntStream mapToInt(ToIntFunction<? super T> mapper)
IntStreamを返す。 これは中間処理である。
LongStream mapToLong(ToLongFunction<? super T> mapper)
LongStreamを返す。 これは中間処理である。
DoubleStream mapToDouble(ToDoubleFunction<? super T> mapper)
DoubleStreamを返す。 これは中間処理である。
LongStream flatMapToLong(Function<? super T,? extends LongStream> mapper)
DoubleStream flatMapToDouble(Function<? super T,? extends DoubleStream> mapper)
Stream<T> distinct()
Object.equals(Object)に従って)重複を除いた要素からなるストリームを返す。 順序を持つストリームの場合、重複を除いた要素の選択は安定的である(重複する要素の場合、出現順で最初に表われた要素が保存される)。順序を持たないストリームの場合、安定性は保障されない。
これは状態を持つ中間処理である。
Stream<T> sorted()
Comparableでなければ、末端処理を実行した際にjava.lang.ClassCastExceptionが投げられる場合がある。 順序を持つストリームに対して、整列は安定的である。順序を持たないストリームに対して、安定性の保障は成されない。
これは状態を持つ中間処理である。
Stream<T> sorted(Comparator<? super T> comparator)
Comparatorに従って整列した結果からなるストリームを返す。 順序を持つストリームに対して、整列は安定的である。順序を持たないストリームに対して、安定性の保障は成されない。
これは状態を持つ中間処理である。
Stream<T> peek(Consumer<? super T> action)
これは中間処理である。
並列ストリームパイプラインの場合、アクションは上流の処理から利用可能になった際に任意の時間と任意のスレッドで呼ばれる。もしアクションが共有状態を変更した場合、必要な同期を用意する必要がある。
Stream<T> limit(long maxSize)
maxSizeより長くならないように切り詰められたストリームを返す。 これは短絡的で状態を持つ中間処理である。
void forEach(Consumer<? super T> action)
これは末端処理である。
この処理の挙動は非決定的であると明示的に定められている。並列ストリームパイプラインの場合、この処理はストリームの出現順順序を尊重するとは限らない。そのようにしてしまうと並列処理の利点を犠牲にしてしまうためである。与えられた要素に対して、アクションはライブラリが選んだ任意の時間と任意のスレッドで実行される。もしアクションが共有状態を変更するならば、アクションは必要な同期処理を用意する責任を負う。
void forEachOrdered(Consumer<? super T> action)
これは末端処理である。
この処理では出現順順序がある場合、出現順に従って要素を一度に1つずつ処理する。1つの要素へのアクションは続く要素に対するアクションの実行の前に発生(happens-before)するが、与えられた要素に対してアクションはライブラリが選択した任意のスレッドで実行される。
Object[] toArray()
これは末端処理である。
<A> A[] toArray(IntFunction<A[]> generator)
generator関数を使って返り値の配列や、分割実行やリサイズ時に必要となる配列を確保する。 これは末端処理である。
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と等しい。accumulator関数は結合的関数である必要がある。
これは末端処理である。
Optional<T> reduce(BinaryOperator<T> accumulator)
Optinoalを返す。これは次と等しい。
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関数は結合的関数である必要がある。
これは末端処理である。
<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.apply(identity, u)がuに等しいということである。加えて、combiner関数はaccumulator関数と適合する必要がある。つまり任意のuとtについて次の式が成り立つ必要がある。
combiner.apply(u, accumulator.apply(identity, t)) == accumulator.apply(u, t)
これは末端処理である。
<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;
reduce(Object, BinaryOperator)のように、collect処理は追加の同期処理を必要とせずに並列化できる。
これは末端処理である。
<R,A> R collect(Collector<? super T,A,R> collector)
Collectorを使ってこのストリームの要素に可変的簡約を実行する。Collectorはcollect(Supplier, BiConsumer, BiConsumer)の引数として使われる関数をカプセル化し、収集戦略の再利用を可能にすると共に、複数レベルのグループ化や組分けなどといった風に収集処理の合成を可能にする。 もしストリームが並列で、Collectorが並行的であり、ストリームが順序を持たないかコレクタが順序を持たない場合、並行簡約が実行される(並行簡約についてはCollectorを見よ)。
これは末端処理である。
並列に実行された場合、可変なデータ構造の隔離を維持するために複数の中間結果がインスタンス化され、満たされ、併合される。そのため(ArrayListなどの)スレッドセーフでないデータ構造に対して並列に実行されたとしても、並列簡約のために追加の同期処理は必要ない。
long count()
boolean anyMatch(Predicate<? super T> predicate)
falseを返す。 これは短絡的で状態を持つ末端処理である。
boolean allMatch(Predicate<? super T> predicate)
trueを返す。 これは短絡的で状態を持つ末端処理である。
boolean noneMatch(Predicate<? super T> predicate)
trueを返す。 これは短絡的で状態を持つ末端処理である。
Optional<T> findFirst()
Optional、もしくはストリームが空であれば空のOptionalを返す。このストリームが出現順順序を持たなければ任意の要素が返される場合がある。 これは短絡的で状態を持つ末端処理である。
Optional<T> findAny()
Optional、もしくはストリームが空であれば空のOptionalを返す。 これは短絡的で状態を持つ末端処理である。
この処理の動作は明示的に非決定的であり、どの要素を選んでもよい。これにより並列実行時の性能を最大化できる。その際のコストは同じ情報源に対する複数回の呼び出しが同じ値を返さないことである(もし安定した結果を望むならば、代わりにfindFirst()を用いよ)。
static <T> Stream.Builder<T> builder()
Streamのビルダを返す。
static <T> Stream<T> empty()
Streamを返す。
static <T> Stream<T> of(T t)
Streamを返す。
@SafeVarargs static <T> Stream<T> of(T... values)
static <T> Stream<T> iterate(T seed, UnaryOperator<T> f)
seedに対する関数fの繰り返しの適用によって生成された無限Streamを返す。seed, f(seed), f(f(seed))などからなるストームを生成する。 Streamの最初の要素(位置0)はseedによって与えられる。n > 0に対しては、位置nの要素はfを位置n - 1の要素に適用した結果である。
static <T> Stream<T> generate(Supplier<T> s)
Supplierによって生成される、逐次的な無限Streamを返す。定数のストリームや乱数のストリームなどを生成するのに向いている。