mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 15:24:43 +02:00
8071597: Add Stream dropWhile and takeWhile operations
Reviewed-by: briangoetz, smarks, chegar, forax
This commit is contained in:
parent
5d91ae3352
commit
5744f4fc30
18 changed files with 3665 additions and 41 deletions
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -272,6 +272,135 @@ public interface IntStream extends BaseStream<Integer, IntStream> {
|
|||
*/
|
||||
IntStream skip(long n);
|
||||
|
||||
/**
|
||||
* Returns, if this stream is ordered, a stream consisting of the longest
|
||||
* prefix of elements taken from this stream that match the given predicate.
|
||||
* Otherwise returns, if this stream is unordered, a stream consisting of a
|
||||
* subset of elements taken from this stream that match the given predicate.
|
||||
*
|
||||
* <p>If this stream is ordered then the longest prefix is a contiguous
|
||||
* sequence of elements of this stream that match the given predicate. The
|
||||
* first element of the sequence is the first element of this stream, and
|
||||
* the element immediately following the last element of the sequence does
|
||||
* not match the given predicate.
|
||||
*
|
||||
* <p>If this stream is unordered, and some (but not all) elements of this
|
||||
* stream match the given predicate, then the behavior of this operation is
|
||||
* nondeterministic; it is free to take any subset of matching elements
|
||||
* (which includes the empty set).
|
||||
*
|
||||
* <p>Independent of whether this stream is ordered or unordered if all
|
||||
* elements of this stream match the given predicate then this operation
|
||||
* takes all elements (the result is the same is the input), or if no
|
||||
* elements of the stream match the given predicate then no elements are
|
||||
* taken (the result is an empty stream).
|
||||
*
|
||||
* <p>This is a <a href="package-summary.html#StreamOps">short-circuiting
|
||||
* stateful intermediate operation</a>.
|
||||
*
|
||||
* @implSpec
|
||||
* The default implementation obtains the {@link #spliterator() spliterator}
|
||||
* of this stream, wraps that spliterator so as to support the semantics
|
||||
* of this operation on traversal, and returns a new stream associated with
|
||||
* the wrapped spliterator. The returned stream preserves the execution
|
||||
* characteristics of this stream (namely parallel or sequential execution
|
||||
* as per {@link #isParallel()}) but the wrapped spliterator may choose to
|
||||
* not support splitting. When the returned stream is closed, the close
|
||||
* handlers for both the returned and this stream are invoked.
|
||||
*
|
||||
* @apiNote
|
||||
* While {@code takeWhile()} is generally a cheap operation on sequential
|
||||
* stream pipelines, it can be quite expensive on ordered parallel
|
||||
* pipelines, since the operation is constrained to return not just any
|
||||
* valid prefix, but the longest prefix of elements in the encounter order.
|
||||
* Using an unordered stream source (such as {@link #generate(IntSupplier)})
|
||||
* or removing the ordering constraint with {@link #unordered()} may result
|
||||
* in significant speedups of {@code takeWhile()} in parallel pipelines, if
|
||||
* the semantics of your situation permit. If consistency with encounter
|
||||
* order is required, and you are experiencing poor performance or memory
|
||||
* utilization with {@code takeWhile()} in parallel pipelines, switching to
|
||||
* sequential execution with {@link #sequential()} may improve performance.
|
||||
*
|
||||
* @param predicate a <a href="package-summary.html#NonInterference">non-interfering</a>,
|
||||
* <a href="package-summary.html#Statelessness">stateless</a>
|
||||
* predicate to apply to elements to determine the longest
|
||||
* prefix of elements.
|
||||
* @return the new stream
|
||||
*/
|
||||
default IntStream takeWhile(IntPredicate predicate) {
|
||||
Objects.requireNonNull(predicate);
|
||||
// Reuses the unordered spliterator, which, when encounter is present,
|
||||
// is safe to use as long as it configured not to split
|
||||
return StreamSupport.intStream(
|
||||
new WhileOps.UnorderedWhileSpliterator.OfInt.Taking(spliterator(), true, predicate),
|
||||
isParallel()).onClose(this::close);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns, if this stream is ordered, a stream consisting of the remaining
|
||||
* elements of this stream after dropping the longest prefix of elements
|
||||
* that match the given predicate. Otherwise returns, if this stream is
|
||||
* unordered, a stream consisting of the remaining elements of this stream
|
||||
* after dropping a subset of elements that match the given predicate.
|
||||
*
|
||||
* <p>If this stream is ordered then the longest prefix is a contiguous
|
||||
* sequence of elements of this stream that match the given predicate. The
|
||||
* first element of the sequence is the first element of this stream, and
|
||||
* the element immediately following the last element of the sequence does
|
||||
* not match the given predicate.
|
||||
*
|
||||
* <p>If this stream is unordered, and some (but not all) elements of this
|
||||
* stream match the given predicate, then the behavior of this operation is
|
||||
* nondeterministic; it is free to drop any subset of matching elements
|
||||
* (which includes the empty set).
|
||||
*
|
||||
* <p>Independent of whether this stream is ordered or unordered if all
|
||||
* elements of this stream match the given predicate then this operation
|
||||
* drops all elements (the result is an empty stream), or if no elements of
|
||||
* the stream match the given predicate then no elements are dropped (the
|
||||
* result is the same is the input).
|
||||
*
|
||||
* <p>This is a <a href="package-summary.html#StreamOps">stateful
|
||||
* intermediate operation</a>.
|
||||
*
|
||||
* @implSpec
|
||||
* The default implementation obtains the {@link #spliterator() spliterator}
|
||||
* of this stream, wraps that spliterator so as to support the semantics
|
||||
* of this operation on traversal, and returns a new stream associated with
|
||||
* the wrapped spliterator. The returned stream preserves the execution
|
||||
* characteristics of this stream (namely parallel or sequential execution
|
||||
* as per {@link #isParallel()}) but the wrapped spliterator may choose to
|
||||
* not support splitting. When the returned stream is closed, the close
|
||||
* handlers for both the returned and this stream are invoked.
|
||||
*
|
||||
* @apiNote
|
||||
* While {@code dropWhile()} is generally a cheap operation on sequential
|
||||
* stream pipelines, it can be quite expensive on ordered parallel
|
||||
* pipelines, since the operation is constrained to return not just any
|
||||
* valid prefix, but the longest prefix of elements in the encounter order.
|
||||
* Using an unordered stream source (such as {@link #generate(IntSupplier)})
|
||||
* or removing the ordering constraint with {@link #unordered()} may result
|
||||
* in significant speedups of {@code dropWhile()} in parallel pipelines, if
|
||||
* the semantics of your situation permit. If consistency with encounter
|
||||
* order is required, and you are experiencing poor performance or memory
|
||||
* utilization with {@code dropWhile()} in parallel pipelines, switching to
|
||||
* sequential execution with {@link #sequential()} may improve performance.
|
||||
*
|
||||
* @param predicate a <a href="package-summary.html#NonInterference">non-interfering</a>,
|
||||
* <a href="package-summary.html#Statelessness">stateless</a>
|
||||
* predicate to apply to elements to determine the longest
|
||||
* prefix of elements.
|
||||
* @return the new stream
|
||||
*/
|
||||
default IntStream dropWhile(IntPredicate predicate) {
|
||||
Objects.requireNonNull(predicate);
|
||||
// Reuses the unordered spliterator, which, when encounter is present,
|
||||
// is safe to use as long as it configured not to split
|
||||
return StreamSupport.intStream(
|
||||
new WhileOps.UnorderedWhileSpliterator.OfInt.Dropping(spliterator(), true, predicate),
|
||||
isParallel()).onClose(this::close);
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs an action for each element of this stream.
|
||||
*
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue