Thinking a little more about dropWhile(),
it can be written using filter() more or less like this:
default Stream<T> dropWhile(Predicate<? super T> predicate) {
return filter(new Predicate<>() {
private boolean noDropAnymore;
public boolean test(T t) {
return noDropAnymore || (noDropAnymore = !predicate.test(t));
}
});
}
and i maybe wrong but implementing dropWhile with an op is not better
than that in term of perf so for me dropWhile() doesn't pull its own weight.
regards,
Rémi
On 06/02/2015 03:13 PM, Paul Sandoz wrote:
Hi,
Please review this webrev that adds take/dropWhile operations to streams:
http://cr.openjdk.java.net/~psandoz/jdk9/JDK-8071597-take-drop-while/webrev/
I opted to weight the documentation of the operations towards ordered streams in the
first paragraph. That is what makes most sense in terms of usage and what most people
will read. Thus i refer to the "longest prefix" in the first paragraph then
define what that means in subsequent paragraphs for ordered and unordered streams:
482 /**
483 * Returns a stream consisting of the longest prefix of elements
taken from
484 * this stream that match the given predicate.
485 *
486 * <p>If this stream is ordered then the prefix is a contiguous
sequence of
487 * elements of this stream. All elements of the sequence match the
given
488 * predicate, the first element of the sequence is the first element
489 * (if any) of this stream, and the element (if any) immediately
following
490 * the last element of the sequence does not match the given
predicate.
491 *
492 * <p>If this stream is unordered then the prefix is a subset of
elements of
493 * this stream. All elements (if any) of the subset match the given
494 * predicate. In this case the behavior of this operation is
495 * nondeterministic; it is free to select any valid subset as the
prefix.
496 *
497 * <p>This is a <a
href="package-summary.html#StreamOps">short-circuiting
498 * stateful intermediate operation</a>.
499 *
...
528 default Stream<T> takeWhile(Predicate<? super T> predicate) {
537 /**
538 * Returns a stream consisting of the remaining elements of this
stream
539 * after dropping the longest prefix of elements that match the given
540 * predicate.
541 *
542 * <p>If this stream is ordered then the prefix is a contiguous
sequence of
543 * elements of this stream. All elements of the sequence match the
given
544 * predicate, the first element of the sequence is the first element
545 * (if any) of this stream, and the element (if any) immediately
following
546 * the last element of the sequence does not match the given
predicate.
547 *
548 * <p>If this stream is unordered then the prefix is a subset of
elements of
549 * this stream. All elements (if any) of the subset match the given
550 * predicate. In this case the behavior of this operation is
551 * nondeterministic; it is free to select any valid subset as the
prefix.
552 *
...
584 default Stream<T> dropWhile(Predicate<? super T> predicate) {
After this has been reviewed i will follow up with a further issue regarding
the specification of takeWhile, stateful predicates and cancellation. I avoided
such specification here as it's likely to rathole :-)
Basically the takeWhile operation is implemented such that one can do:
long t = System.currentTimeMillis();
List<BigInteger> pps = Stream
.generate(() -> BigInteger.probablePrime(1024,
ThreadLocalRandom.current()))
.parallel()
.takeWhile(e -> (System.currentTimeMillis() - t) <
TimeUnit.SECONDS.toMillis(5))
.collect(toList());
Paul.