diff -r abad00f2c027 -r dbca10d053fd jdk/src/java.base/share/classes/java/util/stream/LongStream.java --- a/jdk/src/java.base/share/classes/java/util/stream/LongStream.java Mon Jul 13 17:44:34 2015 +0800 +++ b/jdk/src/java.base/share/classes/java/util/stream/LongStream.java Tue Jun 09 07:10:03 2015 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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 @@ -24,11 +24,7 @@ */ package java.util.stream; -import java.nio.charset.Charset; -import java.nio.file.Files; -import java.nio.file.Path; import java.util.Arrays; -import java.util.Collection; import java.util.LongSummaryStatistics; import java.util.Objects; import java.util.OptionalDouble; @@ -36,7 +32,6 @@ import java.util.PrimitiveIterator; import java.util.Spliterator; import java.util.Spliterators; -import java.util.concurrent.ConcurrentHashMap; import java.util.function.BiConsumer; import java.util.function.Function; import java.util.function.LongBinaryOperator; @@ -278,6 +273,137 @@ LongStream 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. + * + *

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. + * + *

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). + * + *

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). + * + *

This is a short-circuiting + * stateful intermediate operation. + * + * @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(LongSupplier)}) 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 non-interfering, + * stateless + * predicate to apply to elements to determine the longest + * prefix of elements. + * @return the new stream + */ + default LongStream takeWhile(LongPredicate 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.longStream( + new WhileOps.UnorderedWhileSpliterator.OfLong.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. + * + *

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. + * + *

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). + * + *

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). + * + *

This is a stateful + * intermediate operation. + * + * @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(LongSupplier)}) 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 non-interfering, + * stateless + * predicate to apply to elements to determine the longest + * prefix of elements. + * @return the new stream + */ + default LongStream dropWhile(LongPredicate 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.longStream( + new WhileOps.UnorderedWhileSpliterator.OfLong.Dropping(spliterator(), true, predicate), + isParallel()).onClose(this::close); + } + + /** * Performs an action for each element of this stream. * *

This is a terminal