8072727: add variation of Stream.iterate() that's finite
Reviewed-by: psandoz, briangoetz
This commit is contained in:
parent
2255be0267
commit
90adb4174f
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -949,24 +949,100 @@ public interface DoubleStream extends BaseStream<Double, DoubleStream> {
|
|||||||
*/
|
*/
|
||||||
public static DoubleStream iterate(final double seed, final DoubleUnaryOperator f) {
|
public static DoubleStream iterate(final double seed, final DoubleUnaryOperator f) {
|
||||||
Objects.requireNonNull(f);
|
Objects.requireNonNull(f);
|
||||||
final PrimitiveIterator.OfDouble iterator = new PrimitiveIterator.OfDouble() {
|
Spliterator.OfDouble spliterator = new Spliterators.AbstractDoubleSpliterator(Long.MAX_VALUE,
|
||||||
double t = seed;
|
Spliterator.ORDERED | Spliterator.IMMUTABLE | Spliterator.NONNULL) {
|
||||||
|
double prev;
|
||||||
|
boolean started;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasNext() {
|
public boolean tryAdvance(DoubleConsumer action) {
|
||||||
|
Objects.requireNonNull(action);
|
||||||
|
double t;
|
||||||
|
if (started)
|
||||||
|
t = f.applyAsDouble(prev);
|
||||||
|
else {
|
||||||
|
t = seed;
|
||||||
|
started = true;
|
||||||
|
}
|
||||||
|
action.accept(prev = t);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return StreamSupport.doubleStream(spliterator, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a sequential ordered {@code DoubleStream} produced by iterative
|
||||||
|
* application of a function to an initial element, conditioned on
|
||||||
|
* satisfying the supplied predicate. The stream terminates as soon as
|
||||||
|
* the predicate returns false.
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* {@code DoubleStream.iterate} should produce the same sequence of
|
||||||
|
* elements as produced by the corresponding for-loop:
|
||||||
|
* <pre>{@code
|
||||||
|
* for (double index=seed; predicate.test(index); index = f.apply(index)) {
|
||||||
|
* ...
|
||||||
|
* }
|
||||||
|
* }</pre>
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* The resulting sequence may be empty if the predicate does not hold on
|
||||||
|
* the seed value. Otherwise the first element will be the supplied seed
|
||||||
|
* value, the next element (if present) will be the result of applying the
|
||||||
|
* function f to the seed value, and so on iteratively until the predicate
|
||||||
|
* indicates that the stream should terminate.
|
||||||
|
*
|
||||||
|
* @param seed the initial element
|
||||||
|
* @param predicate a predicate to apply to elements to determine when the
|
||||||
|
* stream must terminate.
|
||||||
|
* @param f a function to be applied to the previous element to produce
|
||||||
|
* a new element
|
||||||
|
* @return a new sequential {@code DoubleStream}
|
||||||
|
* @since 9
|
||||||
|
*/
|
||||||
|
public static DoubleStream iterate(double seed, DoublePredicate predicate, DoubleUnaryOperator f) {
|
||||||
|
Objects.requireNonNull(f);
|
||||||
|
Objects.requireNonNull(predicate);
|
||||||
|
Spliterator.OfDouble spliterator = new Spliterators.AbstractDoubleSpliterator(Long.MAX_VALUE,
|
||||||
|
Spliterator.ORDERED | Spliterator.IMMUTABLE | Spliterator.NONNULL) {
|
||||||
|
double prev;
|
||||||
|
boolean started, finished;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean tryAdvance(DoubleConsumer action) {
|
||||||
|
Objects.requireNonNull(action);
|
||||||
|
if (finished)
|
||||||
|
return false;
|
||||||
|
double t;
|
||||||
|
if (started)
|
||||||
|
t = f.applyAsDouble(prev);
|
||||||
|
else {
|
||||||
|
t = seed;
|
||||||
|
started = true;
|
||||||
|
}
|
||||||
|
if (!predicate.test(t)) {
|
||||||
|
finished = true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
action.accept(prev = t);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public double nextDouble() {
|
public void forEachRemaining(DoubleConsumer action) {
|
||||||
double v = t;
|
Objects.requireNonNull(action);
|
||||||
t = f.applyAsDouble(t);
|
if (finished)
|
||||||
return v;
|
return;
|
||||||
|
finished = true;
|
||||||
|
double t = started ? f.applyAsDouble(prev) : seed;
|
||||||
|
while (predicate.test(t)) {
|
||||||
|
action.accept(t);
|
||||||
|
t = f.applyAsDouble(t);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
return StreamSupport.doubleStream(Spliterators.spliteratorUnknownSize(
|
return StreamSupport.doubleStream(spliterator, false);
|
||||||
iterator,
|
|
||||||
Spliterator.ORDERED | Spliterator.IMMUTABLE | Spliterator.NONNULL), false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -885,28 +885,104 @@ public interface IntStream extends BaseStream<Integer, IntStream> {
|
|||||||
* @param seed the initial element
|
* @param seed the initial element
|
||||||
* @param f a function to be applied to the previous element to produce
|
* @param f a function to be applied to the previous element to produce
|
||||||
* a new element
|
* a new element
|
||||||
* @return A new sequential {@code IntStream}
|
* @return a new sequential {@code IntStream}
|
||||||
*/
|
*/
|
||||||
public static IntStream iterate(final int seed, final IntUnaryOperator f) {
|
public static IntStream iterate(final int seed, final IntUnaryOperator f) {
|
||||||
Objects.requireNonNull(f);
|
Objects.requireNonNull(f);
|
||||||
final PrimitiveIterator.OfInt iterator = new PrimitiveIterator.OfInt() {
|
Spliterator.OfInt spliterator = new Spliterators.AbstractIntSpliterator(Long.MAX_VALUE,
|
||||||
int t = seed;
|
Spliterator.ORDERED | Spliterator.IMMUTABLE | Spliterator.NONNULL) {
|
||||||
|
int prev;
|
||||||
|
boolean started;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasNext() {
|
public boolean tryAdvance(IntConsumer action) {
|
||||||
|
Objects.requireNonNull(action);
|
||||||
|
int t;
|
||||||
|
if (started)
|
||||||
|
t = f.applyAsInt(prev);
|
||||||
|
else {
|
||||||
|
t = seed;
|
||||||
|
started = true;
|
||||||
|
}
|
||||||
|
action.accept(prev = t);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return StreamSupport.intStream(spliterator, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a sequential ordered {@code IntStream} produced by iterative
|
||||||
|
* application of a function to an initial element, conditioned on
|
||||||
|
* satisfying the supplied predicate. The stream terminates as soon as
|
||||||
|
* the predicate returns false.
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* {@code IntStream.iterate} should produce the same sequence of elements
|
||||||
|
* as produced by the corresponding for-loop:
|
||||||
|
* <pre>{@code
|
||||||
|
* for (int index=seed; predicate.test(index); index = f.apply(index)) {
|
||||||
|
* ...
|
||||||
|
* }
|
||||||
|
* }</pre>
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* The resulting sequence may be empty if the predicate does not hold on
|
||||||
|
* the seed value. Otherwise the first element will be the supplied seed
|
||||||
|
* value, the next element (if present) will be the result of applying the
|
||||||
|
* function f to the seed value, and so on iteratively until the predicate
|
||||||
|
* indicates that the stream should terminate.
|
||||||
|
*
|
||||||
|
* @param seed the initial element
|
||||||
|
* @param predicate a predicate to apply to elements to determine when the
|
||||||
|
* stream must terminate.
|
||||||
|
* @param f a function to be applied to the previous element to produce
|
||||||
|
* a new element
|
||||||
|
* @return a new sequential {@code IntStream}
|
||||||
|
* @since 9
|
||||||
|
*/
|
||||||
|
public static IntStream iterate(int seed, IntPredicate predicate, IntUnaryOperator f) {
|
||||||
|
Objects.requireNonNull(f);
|
||||||
|
Objects.requireNonNull(predicate);
|
||||||
|
Spliterator.OfInt spliterator = new Spliterators.AbstractIntSpliterator(Long.MAX_VALUE,
|
||||||
|
Spliterator.ORDERED | Spliterator.IMMUTABLE | Spliterator.NONNULL) {
|
||||||
|
int prev;
|
||||||
|
boolean started, finished;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean tryAdvance(IntConsumer action) {
|
||||||
|
Objects.requireNonNull(action);
|
||||||
|
if (finished)
|
||||||
|
return false;
|
||||||
|
int t;
|
||||||
|
if (started)
|
||||||
|
t = f.applyAsInt(prev);
|
||||||
|
else {
|
||||||
|
t = seed;
|
||||||
|
started = true;
|
||||||
|
}
|
||||||
|
if (!predicate.test(t)) {
|
||||||
|
finished = true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
action.accept(prev = t);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int nextInt() {
|
public void forEachRemaining(IntConsumer action) {
|
||||||
int v = t;
|
Objects.requireNonNull(action);
|
||||||
t = f.applyAsInt(t);
|
if (finished)
|
||||||
return v;
|
return;
|
||||||
|
finished = true;
|
||||||
|
int t = started ? f.applyAsInt(prev) : seed;
|
||||||
|
while (predicate.test(t)) {
|
||||||
|
action.accept(t);
|
||||||
|
t = f.applyAsInt(t);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
return StreamSupport.intStream(Spliterators.spliteratorUnknownSize(
|
return StreamSupport.intStream(spliterator, false);
|
||||||
iterator,
|
|
||||||
Spliterator.ORDERED | Spliterator.IMMUTABLE | Spliterator.NONNULL), false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -879,24 +879,100 @@ public interface LongStream extends BaseStream<Long, LongStream> {
|
|||||||
*/
|
*/
|
||||||
public static LongStream iterate(final long seed, final LongUnaryOperator f) {
|
public static LongStream iterate(final long seed, final LongUnaryOperator f) {
|
||||||
Objects.requireNonNull(f);
|
Objects.requireNonNull(f);
|
||||||
final PrimitiveIterator.OfLong iterator = new PrimitiveIterator.OfLong() {
|
Spliterator.OfLong spliterator = new Spliterators.AbstractLongSpliterator(Long.MAX_VALUE,
|
||||||
long t = seed;
|
Spliterator.ORDERED | Spliterator.IMMUTABLE | Spliterator.NONNULL) {
|
||||||
|
long prev;
|
||||||
|
boolean started;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasNext() {
|
public boolean tryAdvance(LongConsumer action) {
|
||||||
|
Objects.requireNonNull(action);
|
||||||
|
long t;
|
||||||
|
if (started)
|
||||||
|
t = f.applyAsLong(prev);
|
||||||
|
else {
|
||||||
|
t = seed;
|
||||||
|
started = true;
|
||||||
|
}
|
||||||
|
action.accept(prev = t);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return StreamSupport.longStream(spliterator, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a sequential ordered {@code LongStream} produced by iterative
|
||||||
|
* application of a function to an initial element, conditioned on
|
||||||
|
* satisfying the supplied predicate. The stream terminates as soon as
|
||||||
|
* the predicate returns false.
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* {@code LongStream.iterate} should produce the same sequence of elements
|
||||||
|
* as produced by the corresponding for-loop:
|
||||||
|
* <pre>{@code
|
||||||
|
* for (long index=seed; predicate.test(index); index = f.apply(index)) {
|
||||||
|
* ...
|
||||||
|
* }
|
||||||
|
* }</pre>
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* The resulting sequence may be empty if the predicate does not hold on
|
||||||
|
* the seed value. Otherwise the first element will be the supplied seed
|
||||||
|
* value, the next element (if present) will be the result of applying the
|
||||||
|
* function f to the seed value, and so on iteratively until the predicate
|
||||||
|
* indicates that the stream should terminate.
|
||||||
|
*
|
||||||
|
* @param seed the initial element
|
||||||
|
* @param predicate a predicate to apply to elements to determine when the
|
||||||
|
* stream must terminate.
|
||||||
|
* @param f a function to be applied to the previous element to produce
|
||||||
|
* a new element
|
||||||
|
* @return a new sequential {@code LongStream}
|
||||||
|
* @since 9
|
||||||
|
*/
|
||||||
|
public static LongStream iterate(long seed, LongPredicate predicate, LongUnaryOperator f) {
|
||||||
|
Objects.requireNonNull(f);
|
||||||
|
Objects.requireNonNull(predicate);
|
||||||
|
Spliterator.OfLong spliterator = new Spliterators.AbstractLongSpliterator(Long.MAX_VALUE,
|
||||||
|
Spliterator.ORDERED | Spliterator.IMMUTABLE | Spliterator.NONNULL) {
|
||||||
|
long prev;
|
||||||
|
boolean started, finished;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean tryAdvance(LongConsumer action) {
|
||||||
|
Objects.requireNonNull(action);
|
||||||
|
if (finished)
|
||||||
|
return false;
|
||||||
|
long t;
|
||||||
|
if (started)
|
||||||
|
t = f.applyAsLong(prev);
|
||||||
|
else {
|
||||||
|
t = seed;
|
||||||
|
started = true;
|
||||||
|
}
|
||||||
|
if (!predicate.test(t)) {
|
||||||
|
finished = true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
action.accept(prev = t);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long nextLong() {
|
public void forEachRemaining(LongConsumer action) {
|
||||||
long v = t;
|
Objects.requireNonNull(action);
|
||||||
t = f.applyAsLong(t);
|
if (finished)
|
||||||
return v;
|
return;
|
||||||
|
finished = true;
|
||||||
|
long t = started ? f.applyAsLong(prev) : seed;
|
||||||
|
while (predicate.test(t)) {
|
||||||
|
action.accept(t);
|
||||||
|
t = f.applyAsLong(t);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
return StreamSupport.longStream(Spliterators.spliteratorUnknownSize(
|
return StreamSupport.longStream(spliterator, false);
|
||||||
iterator,
|
|
||||||
Spliterator.ORDERED | Spliterator.IMMUTABLE | Spliterator.NONNULL), false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -29,7 +29,6 @@ import java.nio.file.Path;
|
|||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.Spliterator;
|
import java.util.Spliterator;
|
||||||
@ -1185,23 +1184,103 @@ public interface Stream<T> extends BaseStream<T, Stream<T>> {
|
|||||||
*/
|
*/
|
||||||
public static<T> Stream<T> iterate(final T seed, final UnaryOperator<T> f) {
|
public static<T> Stream<T> iterate(final T seed, final UnaryOperator<T> f) {
|
||||||
Objects.requireNonNull(f);
|
Objects.requireNonNull(f);
|
||||||
final Iterator<T> iterator = new Iterator<T>() {
|
Spliterator<T> spliterator = new Spliterators.AbstractSpliterator<>(Long.MAX_VALUE,
|
||||||
@SuppressWarnings("unchecked")
|
Spliterator.ORDERED | Spliterator.IMMUTABLE) {
|
||||||
T t = (T) Streams.NONE;
|
T prev;
|
||||||
|
boolean started;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasNext() {
|
public boolean tryAdvance(Consumer<? super T> action) {
|
||||||
|
Objects.requireNonNull(action);
|
||||||
|
T t;
|
||||||
|
if (started)
|
||||||
|
t = f.apply(prev);
|
||||||
|
else {
|
||||||
|
t = seed;
|
||||||
|
started = true;
|
||||||
|
}
|
||||||
|
action.accept(prev = t);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return StreamSupport.stream(spliterator, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a sequential ordered {@code Stream} produced by iterative
|
||||||
|
* application of a function to an initial element, conditioned on
|
||||||
|
* satisfying the supplied predicate. The stream terminates as soon as
|
||||||
|
* the predicate returns false.
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* {@code Stream.iterate} should produce the same sequence of elements as
|
||||||
|
* produced by the corresponding for-loop:
|
||||||
|
* <pre>{@code
|
||||||
|
* for (T index=seed; predicate.test(index); index = f.apply(index)) {
|
||||||
|
* ...
|
||||||
|
* }
|
||||||
|
* }</pre>
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* The resulting sequence may be empty if the predicate does not hold on
|
||||||
|
* the seed value. Otherwise the first element will be the supplied seed
|
||||||
|
* value, the next element (if present) will be the result of applying the
|
||||||
|
* function f to the seed value, and so on iteratively until the predicate
|
||||||
|
* indicates that the stream should terminate.
|
||||||
|
*
|
||||||
|
* @param <T> the type of stream elements
|
||||||
|
* @param seed the initial element
|
||||||
|
* @param predicate a predicate to apply to elements to determine when the
|
||||||
|
* stream must terminate.
|
||||||
|
* @param f a function to be applied to the previous element to produce
|
||||||
|
* a new element
|
||||||
|
* @return a new sequential {@code Stream}
|
||||||
|
* @since 9
|
||||||
|
*/
|
||||||
|
public static<T> Stream<T> iterate(T seed, Predicate<? super T> predicate, UnaryOperator<T> f) {
|
||||||
|
Objects.requireNonNull(f);
|
||||||
|
Objects.requireNonNull(predicate);
|
||||||
|
Spliterator<T> spliterator = new Spliterators.AbstractSpliterator<>(Long.MAX_VALUE,
|
||||||
|
Spliterator.ORDERED | Spliterator.IMMUTABLE) {
|
||||||
|
T prev;
|
||||||
|
boolean started, finished;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean tryAdvance(Consumer<? super T> action) {
|
||||||
|
Objects.requireNonNull(action);
|
||||||
|
if (finished)
|
||||||
|
return false;
|
||||||
|
T t;
|
||||||
|
if (started)
|
||||||
|
t = f.apply(prev);
|
||||||
|
else {
|
||||||
|
t = seed;
|
||||||
|
started = true;
|
||||||
|
}
|
||||||
|
if (!predicate.test(t)) {
|
||||||
|
prev = null;
|
||||||
|
finished = true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
action.accept(prev = t);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public T next() {
|
public void forEachRemaining(Consumer<? super T> action) {
|
||||||
return t = (t == Streams.NONE) ? seed : f.apply(t);
|
Objects.requireNonNull(action);
|
||||||
|
if (finished)
|
||||||
|
return;
|
||||||
|
finished = true;
|
||||||
|
T t = started ? f.apply(prev) : seed;
|
||||||
|
prev = null;
|
||||||
|
while (predicate.test(t)) {
|
||||||
|
action.accept(t);
|
||||||
|
t = f.apply(t);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
return StreamSupport.stream(Spliterators.spliteratorUnknownSize(
|
return StreamSupport.stream(spliterator, false);
|
||||||
iterator,
|
|
||||||
Spliterator.ORDERED | Spliterator.IMMUTABLE), false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -48,14 +48,6 @@ final class Streams {
|
|||||||
throw new Error("no instances");
|
throw new Error("no instances");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* An object instance representing no value, that cannot be an actual
|
|
||||||
* data element of a stream. Used when processing streams that can contain
|
|
||||||
* {@code null} elements to distinguish between a {@code null} value and no
|
|
||||||
* value.
|
|
||||||
*/
|
|
||||||
static final Object NONE = new Object();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An {@code int} range spliterator.
|
* An {@code int} range spliterator.
|
||||||
*/
|
*/
|
||||||
|
@ -126,6 +126,9 @@ public class DoubleStreamTestDataProvider {
|
|||||||
() -> Spliterators.spliterator(isl.iterator(), doubles.length, 0)));
|
() -> Spliterators.spliterator(isl.iterator(), doubles.length, 0)));
|
||||||
spliterators.add(splitDescr("Primitives.s(SpinedBuffer.iterator()):" + name,
|
spliterators.add(splitDescr("Primitives.s(SpinedBuffer.iterator()):" + name,
|
||||||
() -> Spliterators.spliteratorUnknownSize(isl.iterator(), 0)));
|
() -> Spliterators.spliteratorUnknownSize(isl.iterator(), 0)));
|
||||||
|
spliterators.add(splitDescr("DoubleStream.iterate(0,x->x<l;x->x+1):" + name,
|
||||||
|
() -> DoubleStream.iterate(0.0, x -> x < doubles.length, x -> x + 1.0)
|
||||||
|
.spliterator()));
|
||||||
// Need more!
|
// Need more!
|
||||||
}
|
}
|
||||||
spliteratorTestData = spliterators.toArray(new Object[0][]);
|
spliteratorTestData = spliterators.toArray(new Object[0][]);
|
||||||
|
@ -136,6 +136,8 @@ public class IntStreamTestDataProvider {
|
|||||||
() -> IntStream.range(0, ints.length).spliterator()));
|
() -> IntStream.range(0, ints.length).spliterator()));
|
||||||
spliterators.add(splitDescr("IntStream.intRangeClosed(0,l):" + name,
|
spliterators.add(splitDescr("IntStream.intRangeClosed(0,l):" + name,
|
||||||
() -> IntStream.rangeClosed(0, ints.length).spliterator()));
|
() -> IntStream.rangeClosed(0, ints.length).spliterator()));
|
||||||
|
spliterators.add(splitDescr("IntStream.iterate(0,x->x<l,x->x+1): " + name,
|
||||||
|
() -> IntStream.iterate(0, x -> x < ints.length, x -> x + 1).spliterator()));
|
||||||
// Need more!
|
// Need more!
|
||||||
}
|
}
|
||||||
spliteratorTestData = spliterators.toArray(new Object[0][]);
|
spliteratorTestData = spliterators.toArray(new Object[0][]);
|
||||||
|
@ -136,6 +136,9 @@ public class LongStreamTestDataProvider {
|
|||||||
() -> LongStream.range(0, longs.length).spliterator()));
|
() -> LongStream.range(0, longs.length).spliterator()));
|
||||||
spliterators.add(splitDescr("LongStream.longRangeClosed(0,l):" + name,
|
spliterators.add(splitDescr("LongStream.longRangeClosed(0,l):" + name,
|
||||||
() -> LongStream.rangeClosed(0, longs.length).spliterator()));
|
() -> LongStream.rangeClosed(0, longs.length).spliterator()));
|
||||||
|
spliterators.add(splitDescr("LongStream.iterate(0,x->x<l;x->x+1):" + name,
|
||||||
|
() -> LongStream.iterate(0L, x -> x < longs.length, x -> x + 1L)
|
||||||
|
.spliterator()));
|
||||||
// Need more!
|
// Need more!
|
||||||
}
|
}
|
||||||
spliteratorTestData = spliterators.toArray(new Object[0][]);
|
spliteratorTestData = spliterators.toArray(new Object[0][]);
|
||||||
|
@ -171,6 +171,8 @@ public class StreamTestDataProvider {
|
|||||||
() -> Spliterators.spliterator(Arrays.asList(ints).iterator(), ints.length, 0)));
|
() -> Spliterators.spliterator(Arrays.asList(ints).iterator(), ints.length, 0)));
|
||||||
spliterators.add(splitDescr("Iterators.s(Arrays.s(array).iterator()):" + name,
|
spliterators.add(splitDescr("Iterators.s(Arrays.s(array).iterator()):" + name,
|
||||||
() -> Spliterators.spliteratorUnknownSize(Arrays.asList(ints).iterator(), 0)));
|
() -> Spliterators.spliteratorUnknownSize(Arrays.asList(ints).iterator(), 0)));
|
||||||
|
spliterators.add(splitDescr("Stream.iterate(0,x->x<l,x->x+1): " + name,
|
||||||
|
() -> Stream.iterate(0, x -> x < ints.length, x -> x + 1).spliterator()));
|
||||||
// @@@ Add map and collection spliterators when spliterator() is exposed on Collection or Iterable
|
// @@@ Add map and collection spliterators when spliterator() is exposed on Collection or Iterable
|
||||||
}
|
}
|
||||||
spliteratorTestData = spliterators.toArray(new Object[0][]);
|
spliteratorTestData = spliterators.toArray(new Object[0][]);
|
||||||
|
@ -0,0 +1,100 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2016, 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
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
* @bug 8072727
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.openjdk.tests.java.util.stream;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.stream.DoubleStream;
|
||||||
|
import java.util.stream.IntStream;
|
||||||
|
import java.util.stream.LongStream;
|
||||||
|
import java.util.stream.OpTestCase;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
import java.util.stream.TestData;
|
||||||
|
import java.util.stream.TestData.Factory;
|
||||||
|
|
||||||
|
import static java.util.stream.ThowableHelper.checkNPE;
|
||||||
|
|
||||||
|
import org.testng.annotations.DataProvider;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public class IterateTest extends OpTestCase {
|
||||||
|
|
||||||
|
@DataProvider(name = "IterateStreamsData")
|
||||||
|
public static Object[][] makeIterateStreamsTestData() {
|
||||||
|
Object[][] data = {
|
||||||
|
{List.of(),
|
||||||
|
Factory.ofSupplier("ref.empty", () -> Stream.iterate(1, x -> x < 0, x -> x * 2))},
|
||||||
|
{List.of(1),
|
||||||
|
Factory.ofSupplier("ref.one", () -> Stream.iterate(1, x -> x < 2, x -> x * 2))},
|
||||||
|
{List.of(1, 2, 4, 8, 16, 32, 64, 128, 256, 512),
|
||||||
|
Factory.ofSupplier("ref.ten", () -> Stream.iterate(1, x -> x < 1000, x -> x * 2))},
|
||||||
|
{List.of(10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0),
|
||||||
|
Factory.ofSupplier("ref.nullCheck", () -> Stream.iterate(10, Objects::nonNull, x -> x > 0 ? x - 1 : null))},
|
||||||
|
{List.of(),
|
||||||
|
Factory.ofIntSupplier("int.empty", () -> IntStream.iterate(1, x -> x < 0, x -> x + 1))},
|
||||||
|
{List.of(1),
|
||||||
|
Factory.ofIntSupplier("int.one", () -> IntStream.iterate(1, x -> x < 2, x -> x + 1))},
|
||||||
|
{List.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10),
|
||||||
|
Factory.ofIntSupplier("int.ten", () -> IntStream.iterate(1, x -> x <= 10, x -> x + 1))},
|
||||||
|
{List.of(5, 4, 3, 2, 1),
|
||||||
|
Factory.ofIntSupplier("int.divZero", () -> IntStream.iterate(5, x -> x != 0, x -> x - 1/x/2 - 1))},
|
||||||
|
{List.of(),
|
||||||
|
Factory.ofLongSupplier("long.empty", () -> LongStream.iterate(1L, x -> x < 0, x -> x + 1))},
|
||||||
|
{List.of(1L),
|
||||||
|
Factory.ofLongSupplier("long.one", () -> LongStream.iterate(1L, x -> x < 2, x -> x + 1))},
|
||||||
|
{List.of(1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L),
|
||||||
|
Factory.ofLongSupplier("long.ten", () -> LongStream.iterate(1L, x -> x <= 10, x -> x + 1))},
|
||||||
|
{List.of(),
|
||||||
|
Factory.ofDoubleSupplier("double.empty", () -> DoubleStream.iterate(1.0, x -> x < 0, x -> x + 1))},
|
||||||
|
{List.of(1.0),
|
||||||
|
Factory.ofDoubleSupplier("double.one", () -> DoubleStream.iterate(1.0, x -> x < 2, x -> x + 1))},
|
||||||
|
{List.of(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0),
|
||||||
|
Factory.ofDoubleSupplier("double.ten", () -> DoubleStream.iterate(1.0, x -> x <= 10, x -> x + 1))}
|
||||||
|
};
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(dataProvider = "IterateStreamsData")
|
||||||
|
public <T> void testIterate(List<T> expected, TestData<T, ?> data) {
|
||||||
|
withData(data).stream(s -> s).expectedResult(expected).exercise();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testNPE() {
|
||||||
|
checkNPE(() -> Stream.iterate("", null, x -> x + "a"));
|
||||||
|
checkNPE(() -> Stream.iterate("", String::isEmpty, null));
|
||||||
|
checkNPE(() -> IntStream.iterate(0, null, x -> x + 1));
|
||||||
|
checkNPE(() -> IntStream.iterate(0, x -> x < 10, null));
|
||||||
|
checkNPE(() -> LongStream.iterate(0, null, x -> x + 1));
|
||||||
|
checkNPE(() -> LongStream.iterate(0, x -> x < 10, null));
|
||||||
|
checkNPE(() -> DoubleStream.iterate(0, null, x -> x + 1));
|
||||||
|
checkNPE(() -> DoubleStream.iterate(0, x -> x < 10, null));
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user