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.
|
||||
*
|
||||
* 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) {
|
||||
Objects.requireNonNull(f);
|
||||
final PrimitiveIterator.OfDouble iterator = new PrimitiveIterator.OfDouble() {
|
||||
double t = seed;
|
||||
Spliterator.OfDouble spliterator = new Spliterators.AbstractDoubleSpliterator(Long.MAX_VALUE,
|
||||
Spliterator.ORDERED | Spliterator.IMMUTABLE | Spliterator.NONNULL) {
|
||||
double prev;
|
||||
boolean started;
|
||||
|
||||
@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;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double nextDouble() {
|
||||
double v = t;
|
||||
t = f.applyAsDouble(t);
|
||||
return v;
|
||||
public void forEachRemaining(DoubleConsumer action) {
|
||||
Objects.requireNonNull(action);
|
||||
if (finished)
|
||||
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(
|
||||
iterator,
|
||||
Spliterator.ORDERED | Spliterator.IMMUTABLE | Spliterator.NONNULL), false);
|
||||
return StreamSupport.doubleStream(spliterator, 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.
|
||||
*
|
||||
* 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 f a function to be applied to the previous element to produce
|
||||
* 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) {
|
||||
Objects.requireNonNull(f);
|
||||
final PrimitiveIterator.OfInt iterator = new PrimitiveIterator.OfInt() {
|
||||
int t = seed;
|
||||
Spliterator.OfInt spliterator = new Spliterators.AbstractIntSpliterator(Long.MAX_VALUE,
|
||||
Spliterator.ORDERED | Spliterator.IMMUTABLE | Spliterator.NONNULL) {
|
||||
int prev;
|
||||
boolean started;
|
||||
|
||||
@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;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int nextInt() {
|
||||
int v = t;
|
||||
t = f.applyAsInt(t);
|
||||
return v;
|
||||
public void forEachRemaining(IntConsumer action) {
|
||||
Objects.requireNonNull(action);
|
||||
if (finished)
|
||||
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(
|
||||
iterator,
|
||||
Spliterator.ORDERED | Spliterator.IMMUTABLE | Spliterator.NONNULL), false);
|
||||
return StreamSupport.intStream(spliterator, 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.
|
||||
*
|
||||
* 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) {
|
||||
Objects.requireNonNull(f);
|
||||
final PrimitiveIterator.OfLong iterator = new PrimitiveIterator.OfLong() {
|
||||
long t = seed;
|
||||
Spliterator.OfLong spliterator = new Spliterators.AbstractLongSpliterator(Long.MAX_VALUE,
|
||||
Spliterator.ORDERED | Spliterator.IMMUTABLE | Spliterator.NONNULL) {
|
||||
long prev;
|
||||
boolean started;
|
||||
|
||||
@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;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long nextLong() {
|
||||
long v = t;
|
||||
t = f.applyAsLong(t);
|
||||
return v;
|
||||
public void forEachRemaining(LongConsumer action) {
|
||||
Objects.requireNonNull(action);
|
||||
if (finished)
|
||||
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(
|
||||
iterator,
|
||||
Spliterator.ORDERED | Spliterator.IMMUTABLE | Spliterator.NONNULL), false);
|
||||
return StreamSupport.longStream(spliterator, 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.
|
||||
*
|
||||
* 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.Collection;
|
||||
import java.util.Comparator;
|
||||
import java.util.Iterator;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
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) {
|
||||
Objects.requireNonNull(f);
|
||||
final Iterator<T> iterator = new Iterator<T>() {
|
||||
@SuppressWarnings("unchecked")
|
||||
T t = (T) Streams.NONE;
|
||||
Spliterator<T> spliterator = new Spliterators.AbstractSpliterator<>(Long.MAX_VALUE,
|
||||
Spliterator.ORDERED | Spliterator.IMMUTABLE) {
|
||||
T prev;
|
||||
boolean started;
|
||||
|
||||
@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;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T next() {
|
||||
return t = (t == Streams.NONE) ? seed : f.apply(t);
|
||||
public void forEachRemaining(Consumer<? super T> action) {
|
||||
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(
|
||||
iterator,
|
||||
Spliterator.ORDERED | Spliterator.IMMUTABLE), false);
|
||||
return StreamSupport.stream(spliterator, false);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -48,14 +48,6 @@ final class Streams {
|
||||
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.
|
||||
*/
|
||||
|
@ -126,6 +126,9 @@ public class DoubleStreamTestDataProvider {
|
||||
() -> Spliterators.spliterator(isl.iterator(), doubles.length, 0)));
|
||||
spliterators.add(splitDescr("Primitives.s(SpinedBuffer.iterator()):" + name,
|
||||
() -> 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!
|
||||
}
|
||||
spliteratorTestData = spliterators.toArray(new Object[0][]);
|
||||
|
@ -136,6 +136,8 @@ public class IntStreamTestDataProvider {
|
||||
() -> IntStream.range(0, ints.length).spliterator()));
|
||||
spliterators.add(splitDescr("IntStream.intRangeClosed(0,l):" + name,
|
||||
() -> 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!
|
||||
}
|
||||
spliteratorTestData = spliterators.toArray(new Object[0][]);
|
||||
|
@ -136,6 +136,9 @@ public class LongStreamTestDataProvider {
|
||||
() -> LongStream.range(0, longs.length).spliterator()));
|
||||
spliterators.add(splitDescr("LongStream.longRangeClosed(0,l):" + name,
|
||||
() -> 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!
|
||||
}
|
||||
spliteratorTestData = spliterators.toArray(new Object[0][]);
|
||||
|
@ -171,6 +171,8 @@ public class StreamTestDataProvider {
|
||||
() -> Spliterators.spliterator(Arrays.asList(ints).iterator(), ints.length, 0)));
|
||||
spliterators.add(splitDescr("Iterators.s(Arrays.s(array).iterator()):" + name,
|
||||
() -> 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
|
||||
}
|
||||
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