src/share/classes/java/util/stream/DoubleStream.java
Print this page
rev 6980 : [mq]: 7b.JDK-8011918
rev 6981 : [mq]: range
*** 22,40 ****
--- 22,44 ----
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.util.stream;
+ import java.util.Arrays;
import java.util.DoubleSummaryStatistics;
+ import java.util.Objects;
import java.util.OptionalDouble;
import java.util.PrimitiveIterator;
import java.util.Spliterator;
+ import java.util.Spliterators;
import java.util.function.BiConsumer;
import java.util.function.DoubleBinaryOperator;
import java.util.function.DoubleConsumer;
import java.util.function.DoubleFunction;
import java.util.function.DoublePredicate;
+ import java.util.function.DoubleSupplier;
import java.util.function.DoubleToIntFunction;
import java.util.function.DoubleToLongFunction;
import java.util.function.DoubleUnaryOperator;
import java.util.function.Function;
import java.util.function.ObjDoubleConsumer;
*** 647,652 ****
--- 651,825 ----
@Override
PrimitiveIterator.OfDouble iterator();
@Override
Spliterator.OfDouble spliterator();
+
+
+ // Static factories
+
+ /**
+ * Returns a builder for a {@code DoubleStream}.
+ *
+ * @return the stream builder
+ */
+ public static StreamBuilder.OfDouble builder() {
+ return new Streams.DoubleStreamBuilderImpl();
+ }
+
+ /**
+ * Returns an empty sequential {@code DoubleStream}.
+ *
+ * @return an empty sequential stream
+ */
+ public static DoubleStream empty() {
+ return StreamSupport.doubleStream(Spliterators.emptyDoubleSpliterator());
+ }
+
+ /**
+ * Returns a sequential {@code DoubleStream} containing a single element.
+ *
+ * @param t The single element
+ * @return A singleton sequential stream
+ */
+ public static DoubleStream of(double t) {
+ return StreamSupport.doubleStream(new Streams.DoubleStreamBuilderImpl(t));
+ }
+
+ /**
+ * Returns a sequential stream whose elements are the specified values.
+ *
+ * @param values the elements of the new stream
+ * @return the new stream
+ */
+ public static DoubleStream of(double... values) {
+ return Arrays.stream(values);
+ }
+
+ /**
+ * Returns an infinite sequential {@code DoubleStream} produced by iterative
+ * application of a function {@code f} to an initial element {@code seed},
+ * producing a {@code Stream} consisting of {@code seed}, {@code f(seed)},
+ * {@code f(f(seed))}, etc.
+ *
+ * <p>The first element (position {@code 0}) in the {@code DoubleStream} will be
+ * the provided {@code seed}. For {@code n > 0}, the element at position
+ * {@code n}, will be the result of applying the function {@code f} to the
+ * element at position {@code n - 1}.
+ *
+ * @param seed The initial element
+ * @param f The function to be applied to to the previous element to produce
+ * a new element
+ * @return A new sequential {@code DoubleStream}
+ */
+ public static DoubleStream iterate(final double seed, final DoubleUnaryOperator f) {
+ Objects.requireNonNull(f);
+ final PrimitiveIterator.OfDouble iterator = new PrimitiveIterator.OfDouble() {
+ double t = seed;
+
+ @Override
+ public boolean hasNext() {
+ return true;
+ }
+
+ @Override
+ public double nextDouble() {
+ double v = t;
+ t = f.applyAsDouble(t);
+ return v;
+ }
+ };
+ return StreamSupport.doubleStream(Spliterators.spliteratorUnknownSize(
+ iterator,
+ Spliterator.ORDERED | Spliterator.IMMUTABLE | Spliterator.NONNULL));
+ }
+
+ /**
+ * Returns a sequential {@code DoubleStream} where each element is
+ * generated by an {@code DoubleSupplier}. This is suitable for generating
+ * constant streams, streams of random elements, etc.
+ *
+ * @param s the {@code DoubleSupplier} for generated elements
+ * @return A new sequential {@code DoubleStream}
+ */
+ public static DoubleStream generate(DoubleSupplier s) {
+ Objects.requireNonNull(s);
+ return StreamSupport.doubleStream(Spliterators.spliteratorUnknownSize(
+ new PrimitiveIterator.OfDouble() {
+ @Override
+ public boolean hasNext() { return true; }
+
+ @Override
+ public double nextDouble() { return s.getAsDouble(); }
+ },
+ Spliterator.ORDERED | Spliterator.IMMUTABLE | Spliterator.NONNULL));
+ }
+
+ /**
+ * Returns a sequential {@code DoubleStream} from {@code startInclusive} (inclusive)
+ * to {@code endExclusive} (exclusive) by an incremental step of 1.0.
+ *
+ * @implSpec
+ * The implementation behaves as if:
+ * <pre>{@code
+ * doubleRange(startInclusive, endExclusive, 1.0);
+ * }</pre>
+ *
+ * @param startInclusive the (inclusive) initial value
+ * @param endExclusive the exclusive upper bound
+ * @return A sequential {@code DoubleStream} for a range of {@code double}
+ * elements
+ */
+ public static DoubleStream range(double startInclusive, double endExclusive) {
+ return range(startInclusive, endExclusive, 1.0);
+ }
+
+ /**
+ * Returns a sequential {@code DoubleStream} from {@code startInclusive}
+ * (inclusive) to {@code endExclusive} (exclusive) by {@code step}.
+ * If {@code startInclusive} is greater than {@code endExclusive}, an empty
+ * stream is returned.
+ *
+ * An equivalent sequence of increasing values can be produced
+ * sequentially using a {@code for} loop as follows:
+ * <pre>{@code
+ * long size = (long) Math.ceil((startInclusive - endExclusive) / step);
+ * long i = 0
+ * for (double v = startInclusive; i < size; i++, v = startInclusive + step * i) {
+ * ...
+ * }
+ * }</pre>
+ *
+ * @param startInclusive the (inclusive) initial value
+ * @param endExclusive the exclusive upper bound
+ * @param step the difference between consecutive values
+ * @return A sequential {@code DoubleStream} for a range of {@code double}
+ * elements
+ * @throws IllegalArgumentException
+ * if {@code step} is less than or equal to 0,
+ * or the or the count of elements in the range would be greater
+ * than {@code Long.MAX_VALUE} or is {@code NaN}.
+ */
+ public static DoubleStream range(double startInclusive, double endExclusive, double step) {
+ // @@@ Need to check for ranges that may not produce distinct values
+ // such as when the step is very small
+ // Also clarify the size of the range which may produce more or less
+ // than expected
+ if (step <= 0 || Double.isNaN(step))
+ throw new IllegalArgumentException(String.format("Illegal step: %f", step));
+ else if (startInclusive > endExclusive)
+ return empty();
+ else {
+ double size = Math.ceil((endExclusive - startInclusive) / step);
+ if (Double.isNaN(size)) {
+ throw new IllegalArgumentException(
+ String.format("Illegal range: %f size is NaN", size));
+ }
+ else if (size > Long.MAX_VALUE) {
+ throw new IllegalArgumentException(
+ String.format("Illegal range: size %f > Long.MAX_VALUE", size));
+ }
+ else
+ return StreamSupport.doubleStream(new Streams.RangeDoubleSpliterator(startInclusive, endExclusive, step, 0, (long) size));
+ }
+ }
}