undefect. CWE-407 — 63 sites patched across 27 ecosystems

Authors: russell@unturf.com · brackishbert@gmail.com · foxhop.net · TimeHexOn.com

Patches, unit tests, benchmarks, whitepaper, and outreach briefs.
Public domain — no copyright claimed. Use freely.
This commit is contained in:
russell@unturf.com 2026-03-26 17:11:57 -04:00
commit 0a580b313d
70422 changed files with 17213626 additions and 0 deletions

View file

@ -0,0 +1,152 @@
/*
* Copyright (c) 2017, 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
* @summary Tests stream execution in a custom ForkJoinPool
* @bug 8190974
* @run testng/othervm CustomFJPoolTest
* @run testng/othervm -Djava.util.concurrent.ForkJoinPool.common.parallelism=0 CustomFJPoolTest
*/
import org.testng.annotations.Test;
import java.util.Comparator;
import java.util.Spliterator;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;
import java.util.stream.IntStream;
import java.util.stream.StreamSupport;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
@Test
public class CustomFJPoolTest {
// A Spliterator that counts the number of spliterators created
// including itself, thus the count starts at 1
static class SplitCountingSpliterator<T> implements Spliterator<T> {
final Spliterator<T> s;
final AtomicInteger nsplits;
// Top-level constructor
public SplitCountingSpliterator(Spliterator<T> s) {
this.s = s;
nsplits = new AtomicInteger(1);
}
// Splitting constructor
SplitCountingSpliterator(Spliterator<T> s, AtomicInteger nsplits) {
this.s = s;
this.nsplits = nsplits;
}
int splits() {
return nsplits.get();
}
@Override
public boolean tryAdvance(Consumer<? super T> action) {
return s.tryAdvance(action);
}
@Override
public void forEachRemaining(Consumer<? super T> action) {
s.forEachRemaining(action);
}
@Override
public Spliterator<T> trySplit() {
var split = s.trySplit();
if (split != null) {
nsplits.incrementAndGet();
return new SplitCountingSpliterator<>(split, nsplits);
}
else {
return null;
}
}
@Override
public long estimateSize() {
return s.estimateSize();
}
@Override
public long getExactSizeIfKnown() {
return s.getExactSizeIfKnown();
}
@Override
public int characteristics() {
return s.characteristics();
}
@Override
public boolean hasCharacteristics(int characteristics) {
return s.hasCharacteristics(characteristics);
}
@Override
public Comparator<? super T> getComparator() {
return s.getComparator();
}
}
public void testCustomPools() throws Exception {
int splitsForP1 = countSplits(new ForkJoinPool(1));
int splitsForP2 = countSplits(new ForkJoinPool(2));
assertEquals(splitsForP2, splitsForP1 * 2);
int commonParallelism = ForkJoinPool.getCommonPoolParallelism();
if (commonParallelism > 1 && commonParallelism < 128) {
int splitsForPHalfC = countSplits(new ForkJoinPool(commonParallelism / 2));
int splitsForPC = countSplits(ForkJoinPool.commonPool());
assertTrue(splitsForPHalfC < splitsForPC);
assertEquals(splitsForPC / splitsForPHalfC,
nearestPowerOfTwo(commonParallelism) / nearestPowerOfTwo(commonParallelism / 2));
}
}
static int countSplits(ForkJoinPool fjp) throws Exception {
// The number of splits will be equivalent to the number of leaf nodes
// and will be a power of 2
var fInteger = fjp.submit(() -> {
var s = IntStream.range(0, 1024).boxed().parallel().spliterator();
var cs = new SplitCountingSpliterator<>(s);
StreamSupport.stream(cs, true).forEach(e -> {});
return cs.splits();
});
return fInteger.get();
}
static int nearestPowerOfTwo(int i) {
return (i & (i - 1)) == 0
? i
: 1 << (32 - Integer.numberOfLeadingZeros(i));
}
}

View file

@ -0,0 +1,229 @@
/*
* Copyright (c) 2023, 2024, 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.
*/
import java.util.List;
import java.util.Set;
import java.util.function.BiConsumer;
import java.util.function.BinaryOperator;
import java.util.function.Supplier;
import java.util.stream.*;
import java.util.stream.Gatherer;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
import static org.junit.jupiter.api.Assumptions.*;
/**
* @test
* @summary Testing public API of Gatherer
* @run junit GathererAPITest
*/
public class GathererAPITest {
final static Supplier<Void> initializer = () -> (Void)null;
final static Gatherer.Integrator<Void, Integer, Integer> integrator = (v,e,d) -> d.push(e);
final static BinaryOperator<Void> combiner = (l,r) -> l;
final static BiConsumer<Void,Gatherer.Downstream<? super Integer>> finisher = (v,d) -> {};
final static Supplier<Void> nullInitializer = null;
final static Gatherer.Integrator<Void, Integer, Integer> nullIntegrator = null;
final static BinaryOperator<Void> nullCombiner = null;
final static BiConsumer<Void,Gatherer.Downstream<? super Integer>> nullFinisher = null;
private final static <T> Gatherer<T,?,T> passthrough() {
return Gatherer.of(
() -> (Void)null,
Gatherer.Integrator.<Void,T,T>ofGreedy((v,e,d) -> d.push(e)),
(l,r) -> l,
(v,d) -> {}
);
}
private final static <T,A,R> Gatherer<T,A,R> verifyGathererContract(Gatherer<T,A,R> gatherer) {
// basics
assertNotNull(gatherer);
// components
assertNotNull(gatherer.initializer());
assertNotNull(gatherer.integrator());
assertNotNull(gatherer.combiner());
assertNotNull(gatherer.finisher());
assertNotNull(gatherer.andThen(passthrough()));
return gatherer;
}
private final static <T,A,R> Gatherer<T,A,R> verifyGathererStructure(
Gatherer<T,A,R> gatherer,
Supplier<A> expectedSupplier,
Gatherer.Integrator<A,T,R> expectedIntegrator,
BinaryOperator<A> expectedCombiner,
BiConsumer<A,Gatherer.Downstream<? super R>> expectedFinisher
) {
// basics
assertNotNull(gatherer);
// components
assertSame(expectedSupplier, gatherer.initializer());
assertSame(expectedIntegrator, gatherer.integrator());
assertSame(expectedCombiner, gatherer.combiner());
assertSame(expectedFinisher, gatherer.finisher());
return gatherer;
}
@Test
public void testGathererDefaults() {
final Gatherer.Integrator<Void,Void,Void> expectedIntegrator =
(a,b,c) -> false;
class Test implements Gatherer<Void,Void,Void> {
@Override
public Integrator<Void, Void, Void> integrator() {
return expectedIntegrator;
}
}
var t = new Test();
assertSame(Gatherer.<Void>defaultInitializer(), t.initializer());
assertSame(expectedIntegrator, t.integrator());
assertSame(Gatherer.<Void>defaultCombiner(), t.combiner());
assertSame(Gatherer.<Void,Gatherer.Downstream<? super Void>>defaultFinisher(), t.finisher());
}
@Test
public void testDownstreamDefaults() {
class Test implements Gatherer.Downstream<Void> {
@Override public boolean push(Void v) { return false; }
}
var t = new Test();
assertEquals(false, t.isRejecting());
}
@Test
public void testGathererFactoriesNPE() {
assertThrows(NullPointerException.class,
() -> Gatherer.of(nullInitializer, integrator, combiner, finisher));
assertThrows(NullPointerException.class,
() -> Gatherer.of(initializer, nullIntegrator, combiner, finisher));
assertThrows(NullPointerException.class,
() -> Gatherer.of(initializer, integrator, nullCombiner, finisher));
assertThrows(NullPointerException.class,
() -> Gatherer.of(initializer, integrator, combiner, nullFinisher));
assertThrows(NullPointerException.class,
() -> Gatherer.of(nullIntegrator));
assertThrows(NullPointerException.class,
() -> Gatherer.of(nullIntegrator, finisher));
assertThrows(NullPointerException.class,
() -> Gatherer.of(integrator, nullFinisher));
assertThrows(NullPointerException.class,
() -> Gatherer.ofSequential(nullInitializer, integrator));
assertThrows(NullPointerException.class,
() -> Gatherer.ofSequential(initializer, nullIntegrator));
assertThrows(NullPointerException.class,
() -> Gatherer.ofSequential(nullIntegrator));
assertThrows(NullPointerException.class,
() -> Gatherer.ofSequential(nullIntegrator, finisher));
assertThrows(NullPointerException.class,
() -> Gatherer.ofSequential(integrator, nullFinisher));
assertThrows(NullPointerException.class,
() -> Gatherer.ofSequential(nullInitializer, integrator, finisher));
assertThrows(NullPointerException.class,
() -> Gatherer.ofSequential(initializer, nullIntegrator, finisher));
assertThrows(NullPointerException.class,
() -> Gatherer.ofSequential(initializer, integrator, nullFinisher));
}
@Test
public void testGathererFactoriesAPI() {
final var defaultInitializer = Gatherer.<Void>defaultInitializer();
final var defaultCombiner = Gatherer.<Void>defaultCombiner();
final var defaultFinisher = Gatherer.<Void,Integer>defaultFinisher();
var g1 = verifyGathererContract(passthrough()); // Quis custodiet ipsos custodes?
verifyGathererContract(g1.andThen(g1));
var g2 = verifyGathererContract(Gatherer.of(integrator));
verifyGathererContract(g2.andThen(g2));
assertSame(defaultInitializer, g2.initializer());
assertSame(integrator, g2.integrator());
assertNotSame(defaultCombiner, g2.combiner());
assertSame(defaultFinisher, g2.finisher());
var g3 = verifyGathererContract(Gatherer.of(integrator, finisher));
verifyGathererContract(g3.andThen(g3));
assertSame(integrator, g3.integrator());
assertNotSame(defaultCombiner, g3.combiner());
assertSame(finisher, g3.finisher());
var g4 = verifyGathererContract(Gatherer.ofSequential(integrator));
verifyGathererContract(g4.andThen(g4));
verifyGathererStructure(g4, defaultInitializer, integrator, defaultCombiner, defaultFinisher);
var g5 = verifyGathererContract(Gatherer.ofSequential(initializer, integrator));
verifyGathererContract(g5.andThen(g5));
verifyGathererStructure(g5, initializer, integrator, defaultCombiner, defaultFinisher);
var g6 = verifyGathererContract(Gatherer.ofSequential(integrator, finisher));
verifyGathererContract(g6.andThen(g6));
verifyGathererStructure(g6, defaultInitializer, integrator, defaultCombiner, finisher);
var g7 = verifyGathererContract(Gatherer.ofSequential(initializer, integrator, finisher));
verifyGathererContract(g7.andThen(g7));
verifyGathererStructure(g7, initializer, integrator, defaultCombiner, finisher);
var g8 = verifyGathererContract(Gatherer.of(initializer, integrator, combiner, finisher));
verifyGathererContract(g8.andThen(g8));
verifyGathererStructure(g8, initializer, integrator, combiner, finisher);
}
@Test
public void testGathererVariance() {
// Make sure that Gatherers can pass-through type
Gatherer<Number,?,Number> nums = Gatherer.of((unused, element, downstream) -> downstream.push(element));
// Make sure that Gatherers can upcast the output type from the input type
Gatherer<Number,?,Object> upcast = Gatherer.of((unused, element, downstream) -> downstream.push(element));
// Make sure that Gatherers can consume a supertype of the Stream output
assertEquals(List.of(1,2,3,4,5), Stream.<Integer>of(1,2,3,4,5).gather(nums).toList());
Gatherer<Integer,?,Integer> ints = Gatherer.of((unused, element, downstream) -> downstream.push(element));
// Make sure that Gatherers can be composed where the output is a subtype of the input type of the next
Gatherer<Integer,?,Number> composition = ints.andThen(nums);
// Make sure that composition works transitively, typing-wise
Gatherer<Integer,?,Object> upcastComposition = ints.andThen(nums.andThen(upcast));
assertEquals(List.of(1,2,3,4,5), Stream.<Integer>of(1,2,3,4,5).gather(composition).toList());
assertEquals(List.of(1,2,3,4,5), Stream.<Integer>of(1,2,3,4,5).gather(upcastComposition).toList());
}
}

View file

@ -0,0 +1,64 @@
/*
* Copyright (c) 2024, 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.
*/
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Gatherer;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
import static org.junit.jupiter.api.Assumptions.*;
/**
* @test
* @bug 8328316
* @summary Testing Gatherer behavior under short circuiting
* @run junit GathererShortCircuitTest
*/
public class GathererShortCircuitTest {
@Test
public void mustBeAbleToPushFromFinisher() {
Integer expected = 8328316;
List<Integer> source = List.of(1,2,3,4,5);
Gatherer<Integer, ?, Integer> pushOneInFinisher =
Gatherer.of(
(_, element, downstream) -> false,
(_, downstream) -> downstream.push(expected)
);
var usingCollect =
source.stream().gather(pushOneInFinisher).collect(Collectors.toList());
var usingBuiltin =
source.stream().gather(pushOneInFinisher).toList();
var usingCollectPar =
source.stream().parallel().gather(pushOneInFinisher).collect(Collectors.toList());
var usingBuiltinPar =
source.stream().parallel().gather(pushOneInFinisher).toList();
assertEquals(List.of(expected), usingCollect);
assertEquals(List.of(expected), usingBuiltin);
assertEquals(List.of(expected), usingCollectPar);
assertEquals(List.of(expected), usingBuiltinPar);
}
}

View file

@ -0,0 +1,514 @@
/*
* Copyright (c) 2023, 2025, 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.
*/
import java.util.List;
import java.util.Spliterator;
import java.util.function.Consumer;
import java.util.function.Supplier;
import java.util.stream.*;
import java.util.stream.Gatherer;
import static java.util.stream.DefaultMethodStreams.delegateTo;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import org.junit.jupiter.params.provider.ValueSource;
import static org.junit.jupiter.api.Assertions.*;
import static org.junit.jupiter.api.Assumptions.*;
/**
* @test
* @summary Testing the Gatherer contract
* @library /lib/testlibrary/bootlib
* @build java.base/java.util.stream.DefaultMethodStreams
* @run junit GathererTest
*/
public class GathererTest {
record Config(int streamSize, boolean parallel, boolean defaultImpl) {
Stream<Integer> countTo(int n) {
return Stream.iterate(1, i -> i + 1).limit(n);
}
Stream<Integer> stream() {
return wrapStream(countTo(streamSize));
}
<R> Stream<R> wrapStream(Stream<R> stream) {
stream = parallel ? stream.parallel() : stream.sequential();
stream = defaultImpl ? delegateTo(stream) : stream;
return stream;
}
List<Integer> list() {
return stream().toList();
}
}
final static Stream<Config> configurations() {
return Stream.of(0,1,10,33,99,9999)
.flatMap(size ->
Stream.of(false, true)
.flatMap(parallel ->
Stream.of(false, true).map( defaultImpl ->
new Config(size, parallel,
defaultImpl)) )
);
}
final class TestException extends RuntimeException {
TestException(String message) {
super(message);
}
}
final static class InvocationTracker {
int initialize;
int integrate;
int combine;
int finish;
void copyFrom(InvocationTracker other) {
initialize = other.initialize;
integrate = other.integrate;
combine = other.combine;
finish = other.finish;
}
void combine(InvocationTracker other) {
if (other != this) {
initialize += other.initialize;
integrate += other.integrate;
combine += other.combine + 1; // track this merge
finish += other.finish;
}
}
}
final Gatherer<Integer,Void,Integer> addOne = Gatherer.of(
Gatherer.Integrator.<Void,Integer,Integer>ofGreedy((void_state, element, downstream) -> downstream.push(element + 1))
);
final Gatherer<Integer,Void,Integer> timesTwo = Gatherer.of(
Gatherer.Integrator.<Void,Integer,Integer>ofGreedy((void_state, element, downstream) -> downstream.push(element * 2))
);
@ParameterizedTest
@MethodSource("configurations")
public void testInvocationSemanticsGreedy(Config config) {
var result = new InvocationTracker();
var g = Gatherer.<Integer, InvocationTracker, Integer>of(
() -> {
var t = new InvocationTracker();
t.initialize++;
return t;
},
Gatherer.Integrator.<InvocationTracker,Integer,Integer>ofGreedy((t, e, d) -> {
t.integrate++;
return d.push(e);
}),
(t1, t2) -> {
t1.combine(t2);
return t1;
},
(t, d) -> {
t.finish++;
result.copyFrom(t);
});
var res = config.stream().gather(g).toList();
assertEquals(config.countTo(config.streamSize).toList(), res);
if (config.parallel) {
assertTrue(result.initialize > 0);
assertEquals(config.streamSize, result.integrate);
assertTrue(config.streamSize < 2 || result.combine > 0);
assertEquals(1, result.finish);
} else {
assertEquals(1, result.initialize);
assertEquals(config.streamSize, result.integrate);
assertEquals(0, result.combine);
assertEquals(1, result.finish);
}
}
@ParameterizedTest
@MethodSource("configurations")
public void testInvocationSemanticsShortCircuit(Config config) {
final int CONSUME_UNTIL = Math.min(config.streamSize, 5);
var result = new InvocationTracker();
var g = Gatherer.<Integer, InvocationTracker, Integer>of(
() -> {
var t = new InvocationTracker();
t.initialize++;
return t;
},
(t, e, d) -> {
++t.integrate;
return e <= CONSUME_UNTIL && d.push(e) && e != CONSUME_UNTIL;
},
(t1, t2) -> {
t1.combine(t2);
return t1;
},
(t, d) -> {
t.finish++;
result.copyFrom(t);
});
var res = config.stream().gather(g).toList();
assertEquals(config.countTo(CONSUME_UNTIL).toList(), res);
if (config.parallel) {
assertTrue(result.initialize > 0);
assertEquals(CONSUME_UNTIL, result.integrate);
assertTrue(result.combine >= 0); // We can't guarantee split sizes
assertEquals(1, result.finish);
} else {
assertEquals(1, result.initialize);
assertEquals(CONSUME_UNTIL, result.integrate);
assertEquals(0, result.combine);
assertEquals(1, result.finish);
}
}
@ParameterizedTest
@MethodSource("configurations")
public void testEmissionDuringFinisher(Config config) {
var g = Gatherer.<Integer, InvocationTracker, InvocationTracker>of(
() -> {
var t = new InvocationTracker();
t.initialize++;
return t;
},
(t, e, d) -> {
t.integrate++;
return true;
},
(t1, t2) -> {
t1.combine(t2);
return t1;
},
(t, d) -> {
t.finish++;
d.push(t);
});
var resultList = config.stream().gather(g).collect(Collectors.toList());
assertEquals(resultList.size(), 1);
var t = resultList.get(0);
if (config.parallel) {
assertTrue(t.initialize > 0);
assertEquals(config.streamSize, t.integrate);
assertTrue(config.streamSize < 2 || t.combine > 0);
assertEquals(1, t.finish);
} else {
assertEquals(1, t.initialize);
assertEquals(config.streamSize, t.integrate);
assertEquals(0, t.combine);
assertEquals(1, t.finish);
}
}
@ParameterizedTest
@MethodSource("configurations")
public void testInvocationSemanticsShortCircuitDuringCollect(Config config) {
final int CONSUME_UNTIL = Math.min(config.streamSize, 5);
var result = new InvocationTracker();
var g = Gatherer.<Integer, InvocationTracker, Integer>of(
() -> {
var t = new InvocationTracker();
t.initialize++;
return t;
},
(t, e, d) -> {
t.integrate++;
return e <= CONSUME_UNTIL && d.push(e) && e != CONSUME_UNTIL;
},
(t1, t2) -> {
t1.combine(t2);
return t1;
},
(t, d) -> {
t.finish++;
result.copyFrom(t);
});
var res = config.stream().gather(g).collect(Collectors.toList());
assertEquals(config.countTo(CONSUME_UNTIL).toList(), res);
if (config.parallel) {
assertTrue(result.initialize > 0);
assertEquals(CONSUME_UNTIL, result.integrate);
assertTrue(result.combine >= 0); // We can't guarantee split sizes
assertEquals(result.finish, 1);
} else {
assertEquals(result.initialize, 1);
assertEquals(CONSUME_UNTIL, result.integrate);
assertEquals(result.combine, 0);
assertEquals(result.finish, 1);
}
}
@ParameterizedTest
@MethodSource("configurations")
public void testCompositionOfStatelessGatherers(Config config) {
var range = config.stream().toList();
var gRes = range.stream().gather(addOne.andThen(timesTwo)).toList();
var rRes = range.stream().map(j -> j + 1).map(j -> j * 2).toList();
assertEquals(config.streamSize, gRes.size());
assertEquals(config.streamSize, rRes.size());
assertEquals(gRes, rRes);
}
@ParameterizedTest
@MethodSource("configurations")
public void testCompositionOfStatefulGatherers(Config config) {
var t1 = new InvocationTracker();
var g1 = Gatherer.<Integer, InvocationTracker, Integer>of(
() -> {
var t = new InvocationTracker();
t.initialize++;
return t;
},
(t, e, d) -> {
t.integrate++;
return d.push(e);
},
(l, r) -> {
l.combine(r);
return l;
},
(t, d) -> {
t.finish++;
t1.copyFrom(t);
});
var t2 = new InvocationTracker();
var g2 = Gatherer.<Integer, InvocationTracker, Integer>of(
() -> {
var t = new InvocationTracker();
t.initialize++;
return t;
},
(t, e, d) -> {
t.integrate++;
return d.push(e);
},
(l, r) -> {
l.combine(r);
return l;
},
(t, d) -> {
t.finish++;
t2.copyFrom(t);
});
var res = config.stream().gather(g1.andThen(g2)).toList();
assertEquals(config.stream().toList(), res);
if (config.parallel) {
assertTrue(t1.initialize > 0);
assertEquals(config.streamSize, t1.integrate);
assertTrue(config.streamSize < 2 || t1.combine > 0);
assertEquals(1, t1.finish);
assertTrue(t2.initialize > 0);
assertEquals(config.streamSize, t2.integrate);
assertTrue(config.streamSize < 2 || t2.combine > 0);
assertEquals(1, t2.finish);
} else {
assertEquals(1, t1.initialize);
assertEquals(config.streamSize, t1.integrate);
assertEquals(0, t1.combine);
assertEquals(1, t1.finish);
assertEquals(1, t2.initialize);
assertEquals(config.streamSize, t2.integrate);
assertEquals(0, t2.combine);
assertEquals(1, t2.finish);
}
}
@ParameterizedTest
@MethodSource("configurations")
public void testMassivelyComposedGatherers(Config config) {
final int ITERATIONS = 256; // Total number of compositions is 1 + (iterations*2)
Gatherer<Integer,?,Integer> g = addOne;
for(int i = 0;i < ITERATIONS;++i) {
g = g.andThen(timesTwo).andThen(addOne);
}
g = g.andThen(timesTwo);
var ref = config.stream().map(n -> n + 1);
for(int c = 0; c < ITERATIONS; ++c) {
ref = ref.map(n -> n * 2).map(n -> n + 1);
}
ref = ref.map(n -> n * 2);
var gatherered = config.stream().gather(g).toList();
var reference = ref.toList();
assertEquals(gatherered, reference);
}
@Test
public void testUnboundedEmissions() {
Gatherer<Integer,?,Integer> g = Gatherer.of(
() -> (Void)null,
(v,e,d) -> { do {} while(d.push(e)); return false; },
(l,r) -> l,
(v,d) -> {}
);
assertEquals(Stream.of(1).gather(g).limit(1).toList(), List.of(1));
assertEquals(Stream.of(1).gather(g.andThen(g)).limit(1).toList(), List.of(1));
}
@ParameterizedTest
@MethodSource("configurations")
public void testCompositionSymmetry(Config config) {
var consecutiveResult = config.stream().gather(addOne).gather(timesTwo).toList();
var interspersedResult = config.stream().gather(addOne).map(id -> id).gather(timesTwo).toList();
var composedResult = config.stream().gather(addOne.andThen(timesTwo)).toList();
var reference = config.stream().map(j -> j + 1).map(j -> j * 2).toList();
assertEquals(config.streamSize, consecutiveResult.size());
assertEquals(config.streamSize, interspersedResult.size());
assertEquals(config.streamSize, composedResult.size());
assertEquals(config.streamSize, reference.size());
assertEquals(consecutiveResult, reference);
assertEquals(interspersedResult, reference);
assertEquals(composedResult, reference);
}
@ParameterizedTest
@MethodSource("configurations")
public void testExceptionInInitializer(Config config) {
final var expectedMessage = "testExceptionInInitializer()";
assertThrowsTestException(() ->
config.stream().gather(
Gatherer.<Integer,Integer,Integer>of(
() -> { throw new TestException(expectedMessage); },
(i, e, d) -> true,
(l,r) -> l,
(i,d) -> {}
)
).toList(), expectedMessage);
}
@ParameterizedTest
@MethodSource("configurations")
public void testExceptionInIntegrator(Config config) {
if (config.streamSize < 1) return; // No exceptions expected
final var expectedMessage = "testExceptionInIntegrator()";
assertThrowsTestException(() ->
config.stream().gather(
Gatherer.<Integer,Integer,Integer>of(
() -> 1,
(i, e, d) -> { throw new TestException(expectedMessage); },
(l,r) -> l,
(i,d) -> {}
)
).toList()
, expectedMessage);
}
@ParameterizedTest
@MethodSource("configurations")
public void testExceptionInCombiner(Config config) {
if (config.streamSize < 2 || !config.parallel) return; // No exceptions expected
final var expectedMessage = "testExceptionInCombiner()";
assertThrowsTestException(() ->
config.stream().gather(
Gatherer.<Integer,Integer,Integer>of(
() -> 1,
(i, e, d) -> true,
(l,r) -> { throw new TestException(expectedMessage); },
(i,d) -> {}
)
).toList()
, expectedMessage);
}
@ParameterizedTest
@MethodSource("configurations")
public void testExceptionInFinisher(Config config) {
final var expectedMessage = "testExceptionInFinisher()";
assertThrowsTestException(() ->
config.stream().gather(
Gatherer.<Integer,Integer,Integer>of(
() -> 1,
(i, e, d) -> true,
(l,r) -> l,
(v, d) -> { throw new TestException(expectedMessage); }
)
).toList()
, expectedMessage);
}
@ParameterizedTest
@ValueSource(booleans = { false, true })
public void mustNotPropagateSizeInformation(boolean parallel) {
// Constructs a spliterator of unbounded length but which
// reports SIZED and SUBSIZED characteristics so if its size
// of Long.MAX_VALUE gets propagated by gather() then the
// resulting toList() call would allocate a huge array and as
// such would yield an OutOfMemoryError
var s = new Spliterator<Integer>() {
@Override
public boolean tryAdvance(Consumer<? super Integer> action) {
action.accept(0);
return true;
}
@Override public Spliterator<Integer> trySplit() { return null; }
@Override public long estimateSize() { return Long.MAX_VALUE; }
@Override
public int characteristics() {
return Spliterator.SIZED | Spliterator.IMMUTABLE | Spliterator.SUBSIZED;
}
};
var result = StreamSupport.stream(s, parallel)
.gather(
Gatherer.of(
(_, i, d)
-> d.push(i) && false
)
).toList();
assertEquals(result, List.of(0));
}
private final static void assertThrowsTestException(Supplier<?> supplier, String expectedMessage) {
try {
var discard = supplier.get();
} catch (TestException e) {
assertSame(TestException.class, e.getClass());
assertEquals(expectedMessage, e.getMessage());
return;
}
fail("Expected TestException but wasn't thrown!");
}
}

View file

@ -0,0 +1,91 @@
/*
* Copyright (c) 2023, 2024, 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.
*/
import java.util.List;
import java.util.stream.Gatherers;
import java.util.stream.Stream;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import static org.junit.jupiter.api.Assertions.*;
import static org.junit.jupiter.api.Assumptions.*;
/**
* @test
* @summary Tests the API and contract of Gatherers.fold
* @run junit GatherersFoldTest
*/
public class GatherersFoldTest {
record Config(int streamSize, boolean parallel) {
Stream<Integer> stream() {
var stream = Stream.iterate(1, i -> i + 1).limit(streamSize);
stream = parallel ? stream.parallel() : stream.sequential();
return stream;
}
}
static final Stream<Integer> sizes(){
return Stream.of(0,1,10,33,99,9999);
}
static final Stream<Config> sequentialAndParallel(int size) {
return Stream.of(false, true)
.map(parallel ->
new Config(size, parallel));
}
static final Stream<Config> configurations() {
return sizes().flatMap(i -> sequentialAndParallel(i));
}
@Test
public void throwsNPEWhenStateSupplierIsNull() {
assertThrows(NullPointerException.class, () -> Gatherers.<String, String>fold(null, (state, next) -> state));
}
@Test
public void throwsNPEWhenFolderFunctionIsNull() {
assertThrows(NullPointerException.class, () -> Gatherers.<String, String>fold(() -> "", null));
}
@ParameterizedTest
@MethodSource("configurations")
public void behavesAsExpected(Config config) {
final var expectedResult = List.of(
config.stream()
.sequential()
.reduce(0L, (acc, next) -> acc + next,(l, r) -> {
throw new IllegalStateException();
})
);
final var result = config.stream()
.gather(Gatherers.fold(() -> 0L, (acc, next) -> acc + next))
.toList();
assertEquals(expectedResult, result);
}
}

View file

@ -0,0 +1,375 @@
/*
* Copyright (c) 2023, 2025, 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.
*/
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Semaphore;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.locks.LockSupport;
import java.util.function.Function;
import java.util.stream.Gatherer;
import java.util.stream.Gatherers;
import java.util.stream.Stream;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import org.junit.jupiter.params.provider.ValueSource;
import static org.junit.jupiter.api.Assertions.*;
import static org.junit.jupiter.api.Assumptions.*;
/**
* @test
* @summary Tests the API and contract of Gatherers.mapConcurrent
* @run junit GatherersMapConcurrentTest
*/
public class GatherersMapConcurrentTest {
record Config(int streamSize, boolean parallel) {
Stream<Integer> stream() {
var stream = Stream.iterate(1, i -> i + 1).limit(streamSize);
stream = parallel ? stream.parallel() : stream.sequential();
return stream;
}
}
record ConcurrencyConfig(Config config, int concurrencyLevel) {}
static final Stream<Integer> sizes(){
return Stream.of(0,1,10,33,99,9999);
}
static final Stream<Integer> concurrencyLevels() { return Stream.of(1, 2, 3, 10,
1000); }
static final Stream<Config> sequentialAndParallel(int size) {
return Stream.of(false, true)
.map(parallel ->
new Config(size, parallel));
}
static final Stream<Config> configurations() {
return sizes().flatMap(i -> sequentialAndParallel(i));
}
static final Stream<ConcurrencyConfig> concurrencyConfigurations() {
return configurations().flatMap( c -> concurrencyLevels().map( l -> new ConcurrencyConfig(c, l)) );
}
static final Stream<Config> small_atleast3_configurations() {
return sizes().filter(i -> i > 2 && i < 100).flatMap(i -> sequentialAndParallel(i));
}
static final class TestException extends RuntimeException {
TestException(String message) {
super(message);
}
}
@ParameterizedTest
@ValueSource(ints = { Integer.MIN_VALUE, -999, -1, 0})
public void throwsIAEWhenConcurrencyLevelIsLowerThanOne(int level) {
assertThrows(IllegalArgumentException.class,
() -> Gatherers.<String, String>mapConcurrent(level, s -> s));
}
@Test
public void throwsNPEWhenMapperFunctionIsNull() {
assertThrows(NullPointerException.class, () -> Gatherers.<String, String>mapConcurrent(2, null));
}
@ParameterizedTest
@ValueSource(booleans = { true, false } )
public void rethrowsRuntimeExceptionsUnwrapped(boolean parallel) {
final var stream = parallel ? Stream.of(1).parallel() : Stream.of(1);
var exception =
assertThrows(
RuntimeException.class,
() -> stream.gather(
Gatherers.<Integer, Integer>mapConcurrent(2, x -> {
throw new RuntimeException("expected");
})
).toList()
);
assertEquals("expected", exception.getMessage());
assertNull(exception.getCause());
}
@ParameterizedTest
@ValueSource(booleans = { true, false } )
public void rethrowsSubtypesOfRuntimeExceptionsUnwrapped(boolean parallel) {
final var stream = parallel ? Stream.of(1).parallel() : Stream.of(1);
var exception =
assertThrows(
IllegalStateException.class,
() -> stream.gather(
Gatherers.<Integer, Integer>mapConcurrent(2, x -> {
throw new IllegalStateException("expected");
})
).toList()
);
assertEquals("expected", exception.getMessage());
assertNull(exception.getCause());
}
@ParameterizedTest
@ValueSource(booleans = { true, false } )
public void rethrowsErrorsWrappedAsRuntimeExceptions(boolean parallel) {
final var stream = parallel ? Stream.of(1).parallel() : Stream.of(1);
var exception =
assertThrows(
RuntimeException.class,
() -> stream.gather(
Gatherers.<Integer, Integer>mapConcurrent(2, x -> {
throw new Error("expected");
})
).toList()
);
assertEquals("expected", exception.getCause().getMessage());
assertEquals(Error.class, exception.getCause().getClass());
}
@ParameterizedTest
@MethodSource("small_atleast3_configurations")
public void cancelsStartedTasksIfExceptionDuringProcessingIsThrown(Config config) {
final var streamSize = config.streamSize();
assertTrue(streamSize > 2, "This test case won't work with tiny streams!");
final var tasksToCancel = streamSize - 2;
final var throwerReady = new CountDownLatch(1);
final var initiateThrow = new CountDownLatch(1);
final var tasksCancelled = new CountDownLatch(tasksToCancel);
final var tasksWaiting = new Semaphore(0);
try {
config.stream()
.gather(
Gatherers.mapConcurrent(streamSize, i -> {
switch (i) {
case 1 -> {
throwerReady.countDown();
try { initiateThrow.await(); }
catch (InterruptedException ie) {
fail("Unexpected");
}
throw new TestException("expected");
}
case Integer n when n == streamSize -> {
try { throwerReady.await(); }
catch (InterruptedException ie) {
fail("Unexpected");
}
while(tasksWaiting.getQueueLength() < tasksToCancel) {
try {
Thread.sleep(10);
} catch (InterruptedException ie) {
// Ignore
}
}
initiateThrow.countDown();
}
default -> {
try {
tasksWaiting.acquire();
} catch (InterruptedException ie) {
tasksCancelled.countDown(); // used to ensure that they all were interrupted
}
}
}
return i;
})
)
.toList();
fail("This should not be reached");
} catch (TestException te) {
assertEquals("expected", te.getMessage());
try { tasksCancelled.await(); }
catch (InterruptedException ie) {
fail("Unexpected");
}
return;
}
fail("This should not be reached");
}
@ParameterizedTest
@MethodSource("small_atleast3_configurations")
public void cancelsStartedTasksIfShortCircuited(Config config) {
final var streamSize = config.streamSize();
assertTrue(streamSize > 2, "This test case won't work with tiny streams!");
final var tasksToCancel = streamSize - 2;
final var firstReady = new CountDownLatch(1);
final var lastDone = new CountDownLatch(1);
final var tasksCancelled = new CountDownLatch(tasksToCancel);
final var tasksWaiting = new Semaphore(0);
final var result =
config.stream().gather(
Gatherers.mapConcurrent(streamSize, i -> {
switch (i) {
case 1 -> {
firstReady.countDown();
try { lastDone.await(); }
catch (InterruptedException ie) {
fail("Unexpected!");
}
}
case Integer n when n == streamSize -> {
try { firstReady.await(); }
catch (InterruptedException ie) {
fail("Unexpected!");
}
while(tasksWaiting.getQueueLength() < tasksToCancel) {
try {
Thread.sleep(10);
} catch (InterruptedException ie) {
// Ignore
}
}
lastDone.countDown();
}
default -> {
try {
tasksWaiting.acquire();
} catch (InterruptedException ie) {
tasksCancelled.countDown(); // used to ensure that they all were interrupted
}
}
}
return i;
})
)
.gather(Gatherer.of((unused, state, downstream) -> downstream.push(state) && false)) // emulate limit(1)
.toList();
assertEquals(List.of(1), result);
try {
tasksCancelled.await();
} catch (InterruptedException ie) {
fail("Unexpected");
}
}
@ParameterizedTest
@MethodSource("concurrencyConfigurations")
public void behavesAsExpected(ConcurrencyConfig cc) {
final var expectedResult = cc.config().stream()
.map(x -> x * x)
.toList();
final var result = cc.config().stream()
.gather(Gatherers.mapConcurrent(cc.concurrencyLevel(), x -> x * x))
.toList();
assertEquals(expectedResult, result);
}
@ParameterizedTest
@MethodSource("concurrencyConfigurations")
public void shortCircuits(ConcurrencyConfig cc) {
final var limitTo = Math.max(cc.config().streamSize() / 2, 1);
final var expectedResult = cc.config().stream()
.map(x -> x * x)
.limit(limitTo)
.toList();
final var result = cc.config().stream()
.gather(Gatherers.mapConcurrent(cc.concurrencyLevel(), x -> x * x))
.limit(limitTo)
.toList();
assertEquals(expectedResult, result);
}
@ParameterizedTest
@MethodSource("concurrencyConfigurations")
public void ignoresAndRestoresCallingThreadInterruption(ConcurrencyConfig cc) {
final var limitTo = Math.max(cc.config().streamSize() / 2, 1);
final var expectedResult = cc.config().stream()
.map(x -> x * x)
.limit(limitTo)
.toList();
// Ensure calling thread is interrupted
Thread.currentThread().interrupt();
final var result = cc.config().stream()
.gather(Gatherers.mapConcurrent(cc.concurrencyLevel(), x -> {
LockSupport.parkNanos(10000); // 10 us
return x * x;
}))
.limit(limitTo)
.toList();
// Ensure calling thread remains interrupted
assertEquals(true, Thread.interrupted());
assertEquals(expectedResult, result);
}
@ParameterizedTest
@MethodSource("concurrencyConfigurations")
public void limitsWorkInProgressToMaxConcurrency(ConcurrencyConfig cc) {
final var elementNum = new AtomicLong(0);
final var wipCount = new AtomicLong(0);
final var limitTo = Math.max(cc.config().streamSize() / 2, 1);
final var expectedResult = cc.config().stream()
.map(x -> x * x)
.limit(limitTo)
.toList();
Function<Integer, Integer> fun = x -> {
if (wipCount.incrementAndGet() > cc.concurrencyLevel)
throw new IllegalStateException("Too much wip!");
if (elementNum.getAndIncrement() == 0)
LockSupport.parkNanos(500_000_000); // 500 ms
return x * x;
};
final var result = cc.config().stream()
.gather(Gatherers.mapConcurrent(cc.concurrencyLevel(), fun))
.gather(Gatherer.of((v, e, d) -> wipCount.decrementAndGet() >= 0 && d.push(e)))
.limit(limitTo)
.toList();
assertEquals(expectedResult, result);
}
}

View file

@ -0,0 +1,102 @@
/*
* Copyright (c) 2023, 2024, 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.
*/
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Gatherers;
import java.util.stream.Stream;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import static org.junit.jupiter.api.Assertions.*;
import static org.junit.jupiter.api.Assumptions.*;
/**
* @test
* @summary Tests the API and contract of Gatherers.scan
* @run junit GatherersScanTest
*/
public class GatherersScanTest {
record Config(int streamSize, boolean parallel) {
Stream<Integer> stream() {
var stream = Stream.iterate(1, i -> i + 1).limit(streamSize);
stream = parallel ? stream.parallel() : stream.sequential();
return stream;
}
}
static final Stream<Integer> sizes(){
return Stream.of(0,1,10,33,99,9999);
}
static final Stream<Config> sequentialAndParallel(int size) {
return Stream.of(false, true)
.map(parallel ->
new Config(size, parallel));
}
static final Stream<Config> configurations() {
return sizes().flatMap(i -> sequentialAndParallel(i));
}
@Test
public void throwsNPEWhenStateSupplierIsNull() {
assertThrows(NullPointerException.class,
() -> Gatherers.<String, String>scan(null, (state, next) -> state));
}
@Test
public void throwsNPEWhenScannerFunctionIsNull() {
assertThrows(NullPointerException.class,
() -> Gatherers.<String, String>scan(() -> "", null));
}
@ParameterizedTest
@MethodSource("configurations")
public void behavesAsExpected(Config config) {
final List<Long> expectedResult;
if (config.streamSize() == 0) {
expectedResult = List.of();
} else {
expectedResult = config.stream()
.sequential()
.reduce(
new LinkedList<Long>(),
(acc, next) -> {
acc.addLast((acc.isEmpty() ? 0L : acc.getLast()) + next);
return acc;
},
(l, r) -> { throw new IllegalStateException(); }
);
}
final var result = config.stream()
.gather(Gatherers.scan(() -> 0L, (acc, next) -> acc + next))
.toList();
assertEquals(expectedResult, result);
}
}

View file

@ -0,0 +1,133 @@
/*
* Copyright (c) 2023, 2024, 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.
*/
import java.util.Arrays;
import java.util.List;
import java.util.stream.Gatherers;
import java.util.stream.Stream;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import org.junit.jupiter.params.provider.ValueSource;
import static org.junit.jupiter.api.Assertions.*;
import static org.junit.jupiter.api.Assumptions.*;
/**
* @test
* @summary Tests the API and contract of Gatherers.windowFixed
* @run junit GatherersWindowFixedTest
*/
public class GatherersWindowFixedTest {
record Config(int streamSize, boolean parallel) {
Stream<Integer> stream() {
var stream = Stream.iterate(1, i -> i + 1).limit(streamSize);
stream = parallel ? stream.parallel() : stream.sequential();
return stream;
}
}
static final Stream<Integer> sizes(){
return Stream.of(0,1,10,33,99,9999);
}
static final Stream<Config> sequentialAndParallel(int size) {
return Stream.of(false, true)
.map(parallel ->
new Config(size, parallel));
}
static final Stream<Config> configurations() {
return sizes().flatMap(i -> sequentialAndParallel(i));
}
static final Stream<Config> nonempty_configurations() {
return sizes().filter(i -> i > 0).flatMap(i -> sequentialAndParallel(i));
}
@ParameterizedTest
@ValueSource(ints = { Integer.MIN_VALUE, -999, -1, 0})
public void throwsIAEWhenWindowSizeIsSmallerThanOne(int windowSize) {
assertThrows(IllegalArgumentException.class,
() -> Gatherers.windowFixed(windowSize));
}
@ParameterizedTest
@MethodSource("nonempty_configurations")
public void behavesAsExpectedWhenWindowSizeIsSizeOfStream(Config config) {
final var streamSize = config.streamSize();
final var result = config.stream()
.gather(Gatherers.windowFixed(streamSize))
.toList();
assertEquals(1, result.size());
assertEquals(config.stream().toList(), result.get(0));
}
@Test
public void toleratesNullElements() {
assertEquals(
List.of(Arrays.asList(null, null)),
Stream.of(null, null)
.gather(Gatherers.windowFixed(2))
.toList());
}
@Test
public void throwsUOEWhenWindowsAreAttemptedToBeModified() {
var window = Stream.of(1)
.gather(Gatherers.windowFixed(1))
.findFirst()
.get();
assertThrows(UnsupportedOperationException.class,
() -> window.add(2));
}
@ParameterizedTest
@MethodSource("configurations")
public void behavesAsExpected(Config config) {
final var streamSize = config.streamSize();
// Tests that the layout of the returned data is as expected
for (var windowSize : List.of(1, 2, 3, 10)) {
final var expectLastWindowSize = streamSize % windowSize == 0 ? windowSize : streamSize % windowSize;
final var expectedSize = (streamSize / windowSize) + ((streamSize % windowSize == 0) ? 0 : 1);
final var expected = config.stream().toList().iterator();
final var result = config.stream()
.gather(Gatherers.windowFixed(windowSize))
.toList();
int currentWindow = 0;
for (var window : result) {
++currentWindow;
assertEquals(currentWindow < expectedSize ? windowSize : expectLastWindowSize, window.size());
for (var element : window)
assertEquals(expected.next(), element);
}
assertEquals(expectedSize, currentWindow);
}
}
}

View file

@ -0,0 +1,138 @@
/*
* Copyright (c) 2023, 2024, 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.
*/
import java.util.Arrays;
import java.util.List;
import java.util.stream.Gatherers;
import java.util.stream.Stream;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import org.junit.jupiter.params.provider.ValueSource;
import static org.junit.jupiter.api.Assertions.*;
import static org.junit.jupiter.api.Assumptions.*;
/**
* @test
* @summary Tests the API and contract of Gatherers.windowSliding
* @run junit GatherersWindowSlidingTest
*/
public class GatherersWindowSlidingTest {
record Config(int streamSize, boolean parallel) {
Stream<Integer> stream() {
var stream = Stream.iterate(1, i -> i + 1).limit(streamSize);
stream = parallel ? stream.parallel() : stream.sequential();
return stream;
}
}
static final Stream<Integer> sizes(){
return Stream.of(0,1,10,33,99,9999);
}
static final Stream<Config> sequentialAndParallel(int size) {
return Stream.of(false, true)
.map(parallel ->
new Config(size, parallel));
}
static final Stream<Config> configurations() {
return sizes().flatMap(i -> sequentialAndParallel(i));
}
static final Stream<Config> nonempty_configurations() {
return sizes().filter(i -> i > 0).flatMap(i -> sequentialAndParallel(i));
}
@ParameterizedTest
@ValueSource(ints = { Integer.MIN_VALUE, -999, -1, 0})
public void throwsIAEWhenWindowSizeIsSmallerThanOne(int windowSize) {
assertThrows(IllegalArgumentException.class, () -> Gatherers.windowSliding(windowSize));
}
@ParameterizedTest
@MethodSource("nonempty_configurations")
public void behavesAsExpectedWhenWindowSizeIsLargerThanStreamSize(Config config) {
final var streamSize = config.streamSize();
final var result = config.stream()
.gather(Gatherers.windowSliding(streamSize + 1))
.toList();
assertEquals(1, result.size());
assertEquals(config.stream().toList(), result.get(0));
}
@Test
public void toleratesNullElements() {
assertEquals(
List.of(
Arrays.asList(null, null),
Arrays.asList(null, null)
),
Stream.of(null, null, null)
.gather(Gatherers.windowSliding(2))
.toList());
}
@Test
public void throwsUOEWhenWindowsAreAttemptedToBeModified() {
var window = Stream.of(1)
.gather(Gatherers.windowSliding(1))
.findFirst()
.get();
assertThrows(UnsupportedOperationException.class,
() -> window.add(2));
}
@ParameterizedTest
@MethodSource("configurations")
public void behavesAsExpected(Config config) {
final var streamSize = config.streamSize();
// Tests that the layout of the returned data is as expected
for (var windowSize : List.of(1, 2, 3, 10)) {
final var expectLastWindowSize = streamSize < windowSize ? streamSize : windowSize;
final var expectedNumberOfWindows = streamSize == 0 ? 0 : Math.max(1, 1 + streamSize - windowSize);
int expectedElement = 0;
int currentWindow = 0;
final var result = config.stream()
.gather(Gatherers.windowSliding(windowSize))
.toList();
for (var window : result) {
++currentWindow;
assertEquals(currentWindow < expectedNumberOfWindows ? windowSize : expectLastWindowSize, window.size());
for (var element : window) {
assertEquals(++expectedElement, element.intValue());
}
// rewind for the sliding motion
expectedElement -= (window.size() - 1);
}
assertEquals(expectedNumberOfWindows, currentWindow);
}
}
}

View file

@ -0,0 +1 @@
maxOutputSize=2000000

View file

@ -0,0 +1,169 @@
/*
* Copyright (c) 2013, 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.
*/
import java.util.*;
import java.util.function.*;
import java.util.stream.*;
import static java.lang.Double.*;
/*
* @test
* @bug 8006572 8030212
* @summary Test for use of non-naive summation in stream-related sum and average operations.
*/
public class TestDoubleSumAverage {
public static void main(String... args) {
int failures = 0;
failures += testZeroAverageOfNonEmptyStream();
failures += testForCompenstation();
failures += testNonfiniteSum();
if (failures > 0) {
throw new RuntimeException("Found " + failures + " numerical failure(s).");
}
}
/**
* Test to verify that a non-empty stream with a zero average is non-empty.
*/
private static int testZeroAverageOfNonEmptyStream() {
Supplier<DoubleStream> ds = () -> DoubleStream.iterate(0.0, e -> 0.0).limit(10);
return compareUlpDifference(0.0, ds.get().average().getAsDouble(), 0);
}
/**
* Compute the sum and average of a sequence of double values in
* various ways and report an error if naive summation is used.
*/
private static int testForCompenstation() {
int failures = 0;
/*
* The exact sum of the test stream is 1 + 1e6*ulp(1.0) but a
* naive summation algorithm will return 1.0 since (1.0 +
* ulp(1.0)/2) will round to 1.0 again.
*/
double base = 1.0;
double increment = Math.ulp(base)/2.0;
int count = 1_000_001;
double expectedSum = base + (increment * (count - 1));
double expectedAvg = expectedSum / count;
// Factory for double a stream of [base, increment, ..., increment] limited to a size of count
Supplier<DoubleStream> ds = () -> DoubleStream.iterate(base, e -> increment).limit(count);
DoubleSummaryStatistics stats = ds.get().collect(DoubleSummaryStatistics::new,
DoubleSummaryStatistics::accept,
DoubleSummaryStatistics::combine);
failures += compareUlpDifference(expectedSum, stats.getSum(), 3);
failures += compareUlpDifference(expectedAvg, stats.getAverage(), 3);
failures += compareUlpDifference(expectedSum,
ds.get().sum(), 3);
failures += compareUlpDifference(expectedAvg,
ds.get().average().getAsDouble(), 3);
failures += compareUlpDifference(expectedSum,
ds.get().boxed().collect(Collectors.summingDouble(d -> d)), 3);
failures += compareUlpDifference(expectedAvg,
ds.get().boxed().collect(Collectors.averagingDouble(d -> d)),3);
return failures;
}
private static int testNonfiniteSum() {
int failures = 0;
Map<Supplier<DoubleStream>, Double> testCases = new LinkedHashMap<>();
testCases.put(() -> DoubleStream.of(MAX_VALUE, MAX_VALUE), POSITIVE_INFINITY);
testCases.put(() -> DoubleStream.of(-MAX_VALUE, -MAX_VALUE), NEGATIVE_INFINITY);
testCases.put(() -> DoubleStream.of(1.0d, POSITIVE_INFINITY, 1.0d), POSITIVE_INFINITY);
testCases.put(() -> DoubleStream.of(POSITIVE_INFINITY), POSITIVE_INFINITY);
testCases.put(() -> DoubleStream.of(POSITIVE_INFINITY, POSITIVE_INFINITY), POSITIVE_INFINITY);
testCases.put(() -> DoubleStream.of(POSITIVE_INFINITY, POSITIVE_INFINITY, 0.0), POSITIVE_INFINITY);
testCases.put(() -> DoubleStream.of(1.0d, NEGATIVE_INFINITY, 1.0d), NEGATIVE_INFINITY);
testCases.put(() -> DoubleStream.of(NEGATIVE_INFINITY), NEGATIVE_INFINITY);
testCases.put(() -> DoubleStream.of(NEGATIVE_INFINITY, NEGATIVE_INFINITY), NEGATIVE_INFINITY);
testCases.put(() -> DoubleStream.of(NEGATIVE_INFINITY, NEGATIVE_INFINITY, 0.0), NEGATIVE_INFINITY);
testCases.put(() -> DoubleStream.of(1.0d, NaN, 1.0d), NaN);
testCases.put(() -> DoubleStream.of(NaN), NaN);
testCases.put(() -> DoubleStream.of(1.0d, NEGATIVE_INFINITY, POSITIVE_INFINITY, 1.0d), NaN);
testCases.put(() -> DoubleStream.of(1.0d, POSITIVE_INFINITY, NEGATIVE_INFINITY, 1.0d), NaN);
testCases.put(() -> DoubleStream.of(POSITIVE_INFINITY, NaN), NaN);
testCases.put(() -> DoubleStream.of(NEGATIVE_INFINITY, NaN), NaN);
testCases.put(() -> DoubleStream.of(NaN, POSITIVE_INFINITY), NaN);
testCases.put(() -> DoubleStream.of(NaN, NEGATIVE_INFINITY), NaN);
for(Map.Entry<Supplier<DoubleStream>, Double> testCase : testCases.entrySet()) {
Supplier<DoubleStream> ds = testCase.getKey();
double expected = testCase.getValue();
DoubleSummaryStatistics stats = ds.get().collect(DoubleSummaryStatistics::new,
DoubleSummaryStatistics::accept,
DoubleSummaryStatistics::combine);
failures += compareUlpDifference(expected, stats.getSum(), 0);
failures += compareUlpDifference(expected, stats.getAverage(), 0);
failures += compareUlpDifference(expected, ds.get().sum(), 0);
failures += compareUlpDifference(expected, ds.get().average().getAsDouble(), 0);
failures += compareUlpDifference(expected, ds.get().boxed().collect(Collectors.summingDouble(d -> d)), 0);
failures += compareUlpDifference(expected, ds.get().boxed().collect(Collectors.averagingDouble(d -> d)), 0);
}
return failures;
}
/**
* Compute the ulp difference of two double values and compare against an error threshold.
*/
private static int compareUlpDifference(double expected, double computed, double threshold) {
if (!Double.isFinite(expected)) {
// Handle NaN and infinity cases
if (Double.compare(expected, computed) == 0)
return 0;
else {
System.err.printf("Unexpected sum, %g rather than %g.%n",
computed, expected);
return 1;
}
}
double ulpDifference = Math.abs(expected - computed) / Math.ulp(expected);
if (ulpDifference > threshold) {
System.err.printf("Numerical summation error too large, %g ulps rather than %g.%n",
ulpDifference, threshold);
return 1;
} else
return 0;
}
}

View file

@ -0,0 +1,4 @@
# This file identifies root(s) of the test-ng hierarchy.
TestNG.dirs = .
lib.dirs = /lib/testlibrary/bootlib

View file

@ -0,0 +1,47 @@
/*
* Copyright (c) 2012, 2022, 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.
*/
package java.util.stream;
import java.util.*;
public abstract class AbstractSpinedBufferTest {
// Create sizes around the boundary of spines
static final List<Integer> SIZES;
static {
try {
SIZES = IntStream.range(0, 15)
.map(i -> 1 << i)
.flatMap(i -> Arrays.stream(new int[] { i-2, i-1, i, i+1, i+2 }))
.filter(i -> i >= 0)
.boxed()
.distinct()
.collect(Collectors.toList());
}
catch (Exception e) {
throw new IllegalStateException(e);
}
}
static final int TEST_SIZE = 5000;
}

View file

@ -0,0 +1,180 @@
/*
* Copyright (c) 2013, 2017, 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.
*/
package java.util.stream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.PrimitiveIterator;
import java.util.Spliterators;
import java.util.SpliteratorTestHelper;
import java.util.function.Function;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
@Test
public class DoubleNodeTest extends OpTestCase {
@DataProvider(name = "nodes")
public Object[][] createSizes() {
List<Object[]> params = new ArrayList<>();
for (int size : Arrays.asList(0, 1, 4, 15, 16, 17, 127, 128, 129, 1000)) {
double[] array = new double[size];
for (int i = 0; i < array.length; i++) {
array[i] = i;
}
List<Node<Double>> nodes = new ArrayList<>();
nodes.add(Nodes.node(array));
nodes.add(degenerateTree(Spliterators.iterator(Arrays.spliterator(array))));
nodes.add(tree(toList(array), l -> Nodes.node(toDoubleArray(l))));
nodes.add(fill(array, Nodes.doubleBuilder(array.length)));
nodes.add(fill(array, Nodes.doubleBuilder()));
for (Node<Double> node : nodes) {
params.add(new Object[]{array, node});
}
}
return params.toArray(new Object[0][]);
}
private static void assertEqualsListDoubleArray(List<Double> list, double[] array) {
assertEquals(list.size(), array.length);
for (int i = 0; i < array.length; i++)
assertEquals(array[i], (double) list.get(i));
}
private List<Double> toList(double[] a) {
List<Double> l = new ArrayList<>();
for (double i : a) {
l.add(i);
}
return l;
}
private double[] toDoubleArray(List<Double> l) {
double[] a = new double[l.size()];
int i = 0;
for (Double e : l) {
a[i++] = e;
}
return a;
}
private Node.OfDouble fill(double[] array, Node.Builder.OfDouble nb) {
nb.begin(array.length);
for (double i : array)
nb.accept(i);
nb.end();
return nb.build();
}
private Node.OfDouble degenerateTree(PrimitiveIterator.OfDouble it) {
if (!it.hasNext()) {
return Nodes.node(new double[0]);
}
double i = it.nextDouble();
if (it.hasNext()) {
return new Nodes.ConcNode.OfDouble(Nodes.node(new double[] {i}), degenerateTree(it));
}
else {
return Nodes.node(new double[] {i});
}
}
private Node.OfDouble tree(List<Double> l, Function<List<Double>, Node.OfDouble> m) {
if (l.size() < 3) {
return m.apply(l);
}
else {
return new Nodes.ConcNode.OfDouble(
tree(l.subList(0, l.size() / 2), m),
tree(l.subList(l.size() / 2, l.size()), m));
}
}
@Test(dataProvider = "nodes")
public void testAsArray(double[] array, Node.OfDouble n) {
assertEquals(n.asPrimitiveArray(), array);
}
@Test(dataProvider = "nodes")
public void testFlattenAsArray(double[] array, Node.OfDouble n) {
assertEquals(Nodes.flattenDouble(n).asPrimitiveArray(), array);
}
@Test(dataProvider = "nodes")
public void testCopyTo(double[] array, Node.OfDouble n) {
double[] copy = new double[(int) n.count()];
n.copyInto(copy, 0);
assertEquals(copy, array);
}
@Test(dataProvider = "nodes", groups = { "serialization-hostile" })
public void testForEach(double[] array, Node.OfDouble n) {
List<Double> l = new ArrayList<>((int) n.count());
n.forEach((double e) -> {
l.add(e);
});
assertEqualsListDoubleArray(l, array);
}
@Test(dataProvider = "nodes")
public void testStreams(double[] array, Node.OfDouble n) {
TestData.OfDouble data = TestData.Factory.ofNode("Node", n);
exerciseOps(data, s -> s);
exerciseTerminalOps(data, s -> s.toArray());
}
@Test(dataProvider = "nodes", groups={ "serialization-hostile" })
// throws SOE on serialization of DoubleConcNode[size=1000]
public void testSpliterator(double[] array, Node.OfDouble n) {
SpliteratorTestHelper.testDoubleSpliterator(n::spliterator);
}
@Test(dataProvider = "nodes")
public void testTruncate(double[] array, Node.OfDouble n) {
int[] nums = new int[] { 0, 1, array.length / 2, array.length - 1, array.length };
for (int start : nums)
for (int end : nums) {
if (start < 0 || end < 0 || end < start || end > array.length)
continue;
Node.OfDouble slice = n.truncate(start, end, Double[]::new);
double[] asArray = slice.asPrimitiveArray();
for (int k = start; k < end; k++)
assertEquals(array[k], asArray[k - start]);
}
}
}

View file

@ -0,0 +1,283 @@
/*
* Copyright (c) 2012, 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
* 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.
*/
package java.util.stream;
import org.testng.Assert;
import org.testng.annotations.Test;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.List;
import java.util.function.Supplier;
import static java.util.stream.LambdaTestHelpers.countTo;
@Test
public class FlagOpTest extends OpTestCase {
@Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
public void testFlagsPassThrough(String name, TestData<Integer, Stream<Integer>> data) {
@SuppressWarnings({"unchecked", "rawtypes"})
TestFlagPassThroughOp<Integer>[] ops = new TestFlagPassThroughOp[3];
ops[0] = new TestFlagPassThroughOp<>();
ops[1] = new TestFlagPassThroughOp<>();
ops[2] = new TestFlagPassThroughOp<>();
ops[0].set(null, ops[1]);
ops[1].set(ops[0], ops[2]);
ops[2].set(ops[1], null);
withData(data).ops(ops).exercise();
}
static class TestFlagPassThroughOp<T> extends FlagDeclaringOp<T> {
TestFlagPassThroughOp<T> upstream;
TestFlagPassThroughOp<T> downstream;
TestFlagPassThroughOp() {
super(0);
}
void set(TestFlagPassThroughOp<T> upstream, TestFlagPassThroughOp<T> downstream) {
this.upstream = upstream;
this.downstream = downstream;
}
int wrapFlags;
@Override
@SuppressWarnings({"unchecked", "rawtypes"})
public Sink<T> opWrapSink(int flags, boolean parallel, Sink sink) {
this.wrapFlags = flags;
if (downstream != null) {
assertTrue(flags == downstream.wrapFlags);
}
return sink;
}
}
public void testFlagsClearAllSet() {
int clearAllFlags = 0;
for (StreamOpFlag f : EnumSet.allOf(StreamOpFlag.class)) {
if (f.isStreamFlag()) {
clearAllFlags |= f.clear();
}
}
EnumSet<StreamOpFlag> known = EnumSet.noneOf(StreamOpFlag.class);
EnumSet<StreamOpFlag> notKnown = StreamOpFlagTestHelper.allStreamFlags();
List<FlagDeclaringOp<Integer>> ops = new ArrayList<>();
ops.add(new FlagDeclaringOp<>(clearAllFlags));
for (StreamOpFlag f : StreamOpFlagTestHelper.allStreamFlags()) {
if (f.canSet(StreamOpFlag.Type.OP)) {
ops.add(new TestFlagExpectedOp<>(f.set(),
known.clone(),
EnumSet.noneOf(StreamOpFlag.class),
notKnown.clone()));
known.add(f);
notKnown.remove(f);
}
}
ops.add(new TestFlagExpectedOp<>(0,
known.clone(),
EnumSet.noneOf(StreamOpFlag.class),
notKnown.clone()));
TestData<Integer, Stream<Integer>> data = TestData.Factory.ofArray("Array", countTo(10).toArray(new Integer[0]));
@SuppressWarnings("rawtypes")
FlagDeclaringOp[] opsArray = ops.toArray(new FlagDeclaringOp[ops.size()]);
withData(data).ops(opsArray).
without(StreamTestScenario.CLEAR_SIZED_SCENARIOS).
exercise();
}
public void testFlagsSetAllClear() {
EnumSet<StreamOpFlag> known = StreamOpFlagTestHelper.allStreamFlags();
int setAllFlags = 0;
for (StreamOpFlag f : EnumSet.allOf(StreamOpFlag.class)) {
if (f.isStreamFlag()) {
if (f.canSet(StreamOpFlag.Type.OP)) {
setAllFlags |= f.set();
} else {
known.remove(f);
}
}
}
EnumSet<StreamOpFlag> notKnown = EnumSet.noneOf(StreamOpFlag.class);
List<FlagDeclaringOp<Integer>> ops = new ArrayList<>();
ops.add(new FlagDeclaringOp<>(setAllFlags));
for (StreamOpFlag f : StreamOpFlagTestHelper.allStreamFlags()) {
ops.add(new TestFlagExpectedOp<>(f.clear(),
known.clone(),
EnumSet.noneOf(StreamOpFlag.class),
notKnown.clone()));
known.remove(f);
notKnown.add(f);
}
ops.add(new TestFlagExpectedOp<>(0,
known.clone(),
EnumSet.noneOf(StreamOpFlag.class),
notKnown.clone()));
TestData<Integer, Stream<Integer>> data = TestData.Factory.ofArray("Array", countTo(10).toArray(new Integer[0]));
@SuppressWarnings("rawtypes")
FlagDeclaringOp[] opsArray = ops.toArray(new FlagDeclaringOp[ops.size()]);
withData(data).ops(opsArray).
without(StreamTestScenario.CLEAR_SIZED_SCENARIOS).
exercise();
}
public void testFlagsParallelCollect() {
testFlagsSetSequence(CollectorOps::collector);
}
private void testFlagsSetSequence(Supplier<StatefulTestOp<Integer>> cf) {
EnumSet<StreamOpFlag> known = EnumSet.of(StreamOpFlag.ORDERED, StreamOpFlag.SIZED);
EnumSet<StreamOpFlag> preserve = EnumSet.of(StreamOpFlag.DISTINCT, StreamOpFlag.SORTED);
List<IntermediateTestOp<Integer, Integer>> ops = new ArrayList<>();
for (StreamOpFlag f : EnumSet.of(StreamOpFlag.DISTINCT, StreamOpFlag.SORTED)) {
ops.add(cf.get());
ops.add(new TestFlagExpectedOp<>(f.set(),
known.clone(),
preserve.clone(),
EnumSet.noneOf(StreamOpFlag.class)));
known.add(f);
preserve.remove(f);
}
ops.add(cf.get());
ops.add(new TestFlagExpectedOp<>(0,
known.clone(),
preserve.clone(),
EnumSet.noneOf(StreamOpFlag.class)));
TestData<Integer, Stream<Integer>> data = TestData.Factory.ofArray("Array", countTo(10).toArray(new Integer[0]));
@SuppressWarnings("rawtypes")
IntermediateTestOp[] opsArray = ops.toArray(new IntermediateTestOp[ops.size()]);
withData(data).ops(opsArray).
without(StreamTestScenario.CLEAR_SIZED_SCENARIOS).
exercise();
}
public void testFlagsClearParallelCollect() {
testFlagsClearSequence(CollectorOps::collector);
}
protected void testFlagsClearSequence(Supplier<StatefulTestOp<Integer>> cf) {
EnumSet<StreamOpFlag> known = EnumSet.of(StreamOpFlag.ORDERED, StreamOpFlag.SIZED);
EnumSet<StreamOpFlag> preserve = EnumSet.of(StreamOpFlag.DISTINCT, StreamOpFlag.SORTED);
EnumSet<StreamOpFlag> notKnown = EnumSet.noneOf(StreamOpFlag.class);
List<IntermediateTestOp<Integer, Integer>> ops = new ArrayList<>();
for (StreamOpFlag f : EnumSet.of(StreamOpFlag.ORDERED, StreamOpFlag.DISTINCT, StreamOpFlag.SORTED)) {
ops.add(cf.get());
ops.add(new TestFlagExpectedOp<>(f.clear(),
known.clone(),
preserve.clone(),
notKnown.clone()));
known.remove(f);
preserve.remove(f);
notKnown.add(f);
}
ops.add(cf.get());
ops.add(new TestFlagExpectedOp<>(0,
known.clone(),
preserve.clone(),
notKnown.clone()));
TestData<Integer, Stream<Integer>> data = TestData.Factory.ofArray("Array", countTo(10).toArray(new Integer[0]));
@SuppressWarnings("rawtypes")
IntermediateTestOp[] opsArray = ops.toArray(new IntermediateTestOp[ops.size()]);
withData(data).ops(opsArray).
without(StreamTestScenario.CLEAR_SIZED_SCENARIOS).
exercise();
}
public void testFlagsSizedOrderedParallelCollect() {
EnumSet<StreamOpFlag> parKnown = EnumSet.of(StreamOpFlag.SIZED);
EnumSet<StreamOpFlag> serKnown = parKnown.clone();
List<IntermediateTestOp<Integer, Integer>> ops = new ArrayList<>();
for (StreamOpFlag f : parKnown) {
ops.add(CollectorOps.collector());
ops.add(new ParSerTestFlagExpectedOp<>(f.clear(),
parKnown,
serKnown));
serKnown.remove(f);
}
ops.add(CollectorOps.collector());
ops.add(new ParSerTestFlagExpectedOp<>(0,
parKnown,
EnumSet.noneOf(StreamOpFlag.class)));
TestData<Integer, Stream<Integer>> data = TestData.Factory.ofArray("Array", countTo(10).toArray(new Integer[0]));
@SuppressWarnings("rawtypes")
IntermediateTestOp[] opsArray = ops.toArray(new IntermediateTestOp[ops.size()]);
withData(data).ops(opsArray).exercise();
}
static class ParSerTestFlagExpectedOp<T> extends FlagDeclaringOp<T> {
final EnumSet<StreamOpFlag> parKnown;
final EnumSet<StreamOpFlag> serKnown;
ParSerTestFlagExpectedOp(int flags, EnumSet<StreamOpFlag> known, EnumSet<StreamOpFlag> serKnown) {
super(flags);
this.parKnown = known;
this.serKnown = serKnown;
}
@Override
@SuppressWarnings({"unchecked", "rawtypes"})
public Sink<T> opWrapSink(int flags, boolean parallel, Sink upstream) {
assertFlags(flags, parallel);
return upstream;
}
protected void assertFlags(int flags, boolean parallel) {
if (parallel) {
for (StreamOpFlag f : parKnown) {
Assert.assertTrue(f.isKnown(flags), String.format("Flag %s is not known, but should be known.", f.toString()));
}
} else {
for (StreamOpFlag f : serKnown) {
Assert.assertTrue(f.isKnown(flags), String.format("Flag %s is not known, but should be known.", f.toString()));
}
}
}
}
}

View file

@ -0,0 +1,178 @@
/*
* Copyright (c) 2012, 2017, 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.
*/
package java.util.stream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.PrimitiveIterator;
import java.util.Spliterators;
import java.util.SpliteratorTestHelper;
import java.util.function.Function;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
@Test
public class IntNodeTest extends OpTestCase {
@DataProvider(name = "nodes")
public Object[][] createSizes() {
List<Object[]> params = new ArrayList<>();
for (int size : Arrays.asList(0, 1, 4, 15, 16, 17, 127, 128, 129, 1000)) {
int[] array = new int[size];
for (int i = 0; i < array.length; i++) {
array[i] = i;
}
List<Node<Integer>> nodes = new ArrayList<>();
nodes.add(Nodes.node(array));
nodes.add(degenerateTree(Spliterators.iterator(Arrays.spliterator(array))));
nodes.add(tree(toList(array), l -> Nodes.node(toIntArray(l))));
nodes.add(fill(array, Nodes.intBuilder(array.length)));
nodes.add(fill(array, Nodes.intBuilder()));
for (Node<Integer> node : nodes) {
params.add(new Object[]{array, node});
}
}
return params.toArray(new Object[0][]);
}
private static void assertEqualsListIntArray(List<Integer> list, int[] array) {
assertEquals(list.size(), array.length);
for (int i = 0; i < array.length; i++)
assertEquals(array[i], (int) list.get(i));
}
private List<Integer> toList(int[] a) {
List<Integer> l = new ArrayList<>();
for (int i : a) {
l.add(i);
}
return l;
}
private int[] toIntArray(List<Integer> l) {
int[] a = new int[l.size()];
int i = 0;
for (Integer e : l) {
a[i++] = e;
}
return a;
}
private Node.OfInt fill(int[] array, Node.Builder.OfInt nb) {
nb.begin(array.length);
for (int i : array)
nb.accept(i);
nb.end();
return nb.build();
}
private Node.OfInt degenerateTree(PrimitiveIterator.OfInt it) {
if (!it.hasNext()) {
return Nodes.node(new int[0]);
}
int i = it.nextInt();
if (it.hasNext()) {
return new Nodes.ConcNode.OfInt(Nodes.node(new int[] {i}), degenerateTree(it));
}
else {
return Nodes.node(new int[] {i});
}
}
private Node.OfInt tree(List<Integer> l, Function<List<Integer>, Node.OfInt> m) {
if (l.size() < 3) {
return m.apply(l);
}
else {
return new Nodes.ConcNode.OfInt(
tree(l.subList(0, l.size() / 2), m),
tree(l.subList(l.size() / 2, l.size()), m));
}
}
@Test(dataProvider = "nodes")
public void testAsArray(int[] array, Node.OfInt n) {
assertEquals(n.asPrimitiveArray(), array);
}
@Test(dataProvider = "nodes")
public void testFlattenAsArray(int[] array, Node.OfInt n) {
assertEquals(Nodes.flattenInt(n).asPrimitiveArray(), array);
}
@Test(dataProvider = "nodes")
public void testCopyTo(int[] array, Node.OfInt n) {
int[] copy = new int[(int) n.count()];
n.copyInto(copy, 0);
assertEquals(copy, array);
}
@Test(dataProvider = "nodes", groups = { "serialization-hostile" })
public void testForEach(int[] array, Node.OfInt n) {
List<Integer> l = new ArrayList<>((int) n.count());
n.forEach((int e) -> {
l.add(e);
});
assertEqualsListIntArray(l, array);
}
@Test(dataProvider = "nodes")
public void testStreams(int[] array, Node.OfInt n) {
TestData.OfInt data = TestData.Factory.ofNode("Node", n);
exerciseOps(data, s -> s);
exerciseTerminalOps(data, s -> s.toArray());
}
@Test(dataProvider = "nodes")
public void testSpliterator(int[] array, Node.OfInt n) {
SpliteratorTestHelper.testIntSpliterator(n::spliterator);
}
@Test(dataProvider = "nodes")
public void testTruncate(int[] array, Node.OfInt n) {
int[] nums = new int[] { 0, 1, array.length / 2, array.length - 1, array.length };
for (int start : nums)
for (int end : nums) {
if (start < 0 || end < 0 || end < start || end > array.length)
continue;
Node.OfInt slice = n.truncate(start, end, Integer[]::new);
int[] asArray = slice.asPrimitiveArray();
for (int k = start; k < end; k++)
assertEquals(array[k], asArray[k - start]);
}
}
}

View file

@ -0,0 +1,179 @@
/*
* Copyright (c) 2013, 2017, 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.
*/
package java.util.stream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.PrimitiveIterator;
import java.util.Spliterators;
import java.util.SpliteratorTestHelper;
import java.util.function.Function;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
@Test
public class LongNodeTest extends OpTestCase {
@DataProvider(name = "nodes")
public Object[][] createSizes() {
List<Object[]> params = new ArrayList<>();
for (int size : Arrays.asList(0, 1, 4, 15, 16, 17, 127, 128, 129, 1000)) {
long[] array = new long[size];
for (int i = 0; i < array.length; i++) {
array[i] = i;
}
List<Node<Long>> nodes = new ArrayList<>();
nodes.add(Nodes.node(array));
nodes.add(degenerateTree(Spliterators.iterator(Arrays.spliterator(array))));
nodes.add(tree(toList(array), l -> Nodes.node(toLongArray(l))));
nodes.add(fill(array, Nodes.longBuilder(array.length)));
nodes.add(fill(array, Nodes.longBuilder()));
for (Node<Long> node : nodes) {
params.add(new Object[]{array, node});
}
}
return params.toArray(new Object[0][]);
}
private static void assertEqualsListLongArray(List<Long> list, long[] array) {
assertEquals(list.size(), array.length);
for (int i = 0; i < array.length; i++)
assertEquals(array[i], (long) list.get(i));
}
private List<Long> toList(long[] a) {
List<Long> l = new ArrayList<>();
for (long i : a) {
l.add(i);
}
return l;
}
private long[] toLongArray(List<Long> l) {
long[] a = new long[l.size()];
int i = 0;
for (Long e : l) {
a[i++] = e;
}
return a;
}
private Node.OfLong fill(long[] array, Node.Builder.OfLong nb) {
nb.begin(array.length);
for (long i : array)
nb.accept(i);
nb.end();
return nb.build();
}
private Node.OfLong degenerateTree(PrimitiveIterator.OfLong it) {
if (!it.hasNext()) {
return Nodes.node(new long[0]);
}
long i = it.nextLong();
if (it.hasNext()) {
return new Nodes.ConcNode.OfLong(Nodes.node(new long[] {i}), degenerateTree(it));
}
else {
return Nodes.node(new long[] {i});
}
}
private Node.OfLong tree(List<Long> l, Function<List<Long>, Node.OfLong> m) {
if (l.size() < 3) {
return m.apply(l);
}
else {
return new Nodes.ConcNode.OfLong(
tree(l.subList(0, l.size() / 2), m),
tree(l.subList(l.size() / 2, l.size()), m));
}
}
@Test(dataProvider = "nodes")
public void testAsArray(long[] array, Node.OfLong n) {
assertEquals(n.asPrimitiveArray(), array);
}
@Test(dataProvider = "nodes")
public void testFlattenAsArray(long[] array, Node.OfLong n) {
assertEquals(Nodes.flattenLong(n).asPrimitiveArray(), array);
}
@Test(dataProvider = "nodes")
public void testCopyTo(long[] array, Node.OfLong n) {
long[] copy = new long[(int) n.count()];
n.copyInto(copy, 0);
assertEquals(copy, array);
}
@Test(dataProvider = "nodes", groups = { "serialization-hostile" })
public void testForEach(long[] array, Node.OfLong n) {
List<Long> l = new ArrayList<>((int) n.count());
n.forEach((long e) -> {
l.add(e);
});
assertEqualsListLongArray(l, array);
}
@Test(dataProvider = "nodes")
public void testStreams(long[] array, Node.OfLong n) {
TestData.OfLong data = TestData.Factory.ofNode("Node", n);
exerciseOps(data, s -> s);
exerciseTerminalOps(data, s -> s.toArray());
}
@Test(dataProvider = "nodes")
public void testSpliterator(long[] array, Node.OfLong n) {
SpliteratorTestHelper.testLongSpliterator(n::spliterator);
}
@Test(dataProvider = "nodes")
public void testTruncate(long[] array, Node.OfLong n) {
int[] nums = new int[] { 0, 1, array.length / 2, array.length - 1, array.length };
for (int start : nums)
for (int end : nums) {
if (start < 0 || end < 0 || end < start || end > array.length)
continue;
Node.OfLong slice = n.truncate(start, end, Long[]::new);
long[] asArray = slice.asPrimitiveArray();
for (int k = start; k < end; k++)
assertEquals(array[k], asArray[k - start]);
}
}
}

View file

@ -0,0 +1,236 @@
/*
* Copyright (c) 2012, 2013, 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.
*/
package java.util.stream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.DoubleConsumer;
import java.util.function.Function;
import java.util.function.IntConsumer;
import java.util.function.LongConsumer;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import static java.util.stream.LambdaTestHelpers.assertContents;
import static java.util.stream.LambdaTestHelpers.countTo;
import static org.testng.Assert.assertEquals;
@Test
public class NodeBuilderTest {
List<Integer> sizes = Arrays.asList(0, 1, 4, 16, 256,
1023, 1024, 1025,
2047, 2048, 2049,
1024 * 32 - 1, 1024 * 32, 1024 * 32 + 1);
@DataProvider(name = "Node.Builder")
public Object[][] createNodeBuilders() {
List<List<Integer>> ls = new ArrayList<>();
for (int size : sizes) {
ls.add(countTo(size));
}
List<Function<Integer, Node.Builder<Integer>>> ms = Arrays.asList(
s -> Nodes.builder(),
s -> Nodes.builder(s, LambdaTestHelpers.integerArrayGenerator)
);
Object[][] params = new Object[ls.size() * ms.size()][];
int i = 0;
for (List<Integer> l : ls) {
for (Function<Integer, Node.Builder<Integer>> m : ms) {
params[i++] = new Object[]{l, m};
}
}
return params;
}
@Test(dataProvider = "Node.Builder", groups = { "serialization-hostile" })
public void testIteration(List<Integer> l, Function<Integer, Node.Builder<Integer>> m) {
Node.Builder<Integer> nb = m.apply(l.size());
nb.begin(l.size());
for (Integer i : l) {
nb.accept(i);
}
nb.end();
Node<Integer> n = nb.build();
assertEquals(n.count(), l.size());
{
List<Integer> _l = new ArrayList<>();
n.forEach(_l::add);
assertContents(_l, l);
}
}
// Node.Builder.OfInt
@DataProvider(name = "Node.Builder<Integer>")
public Object[][] createIntNodeBuilders() {
List<List<Integer>> ls = new ArrayList<>();
for (int size : sizes) {
ls.add(countTo(size));
}
List<Function<Integer, Node.Builder<Integer>>> ms = Arrays.asList(
s -> Nodes.intBuilder(),
s -> Nodes.intBuilder(s)
);
Object[][] params = new Object[ls.size() * ms.size()][];
int i = 0;
for (List<Integer> l : ls) {
for (Function<Integer, Node.Builder<Integer>> m : ms) {
params[i++] = new Object[]{l, m};
}
}
return params;
}
@Test(dataProvider = "Node.Builder<Integer>", groups = { "serialization-hostile" })
public void testIntIteration(List<Integer> l, Function<Integer, Node.Builder.OfInt> m) {
Node.Builder.OfInt nb = m.apply(l.size());
nb.begin(l.size());
for (Integer i : l) {
nb.accept((int) i);
}
nb.end();
Node.OfInt n = nb.build();
assertEquals(n.count(), l.size());
{
List<Integer> _l = new ArrayList<>();
n.forEach((IntConsumer) _l::add);
assertContents(_l, l);
}
}
// Node.Builder.OfLong
@DataProvider(name = "Node.Builder<Long>")
public Object[][] createLongNodeBuilders() {
List<List<Long>> ls = new ArrayList<>();
for (int size : sizes) {
List<Long> l = new ArrayList<>();
for (long i = 0; i < size; i++) {
l.add(i);
}
ls.add(l);
}
List<Function<Integer, Node.Builder<Long>>> ms = Arrays.asList(
s -> Nodes.longBuilder(),
s -> Nodes.longBuilder(s)
);
Object[][] params = new Object[ls.size() * ms.size()][];
int i = 0;
for (List<Long> l : ls) {
for (Function<Integer, Node.Builder<Long>> m : ms) {
params[i++] = new Object[]{l, m};
}
}
return params;
}
@Test(dataProvider = "Node.Builder<Long>")
public void testLongIteration(List<Long> l, Function<Integer, Node.Builder.OfLong> m) {
Node.Builder.OfLong nb = m.apply(l.size());
nb.begin(l.size());
for (Long i : l) {
nb.accept((long) i);
}
nb.end();
Node.OfLong n = nb.build();
assertEquals(n.count(), l.size());
{
List<Long> _l = new ArrayList<>();
n.forEach((LongConsumer) _l::add);
assertContents(_l, l);
}
}
// Node.Builder.OfDouble
@DataProvider(name = "Node.Builder<Double>")
public Object[][] createDoubleNodeBuilders() {
List<List<Double>> ls = new ArrayList<>();
for (int size : sizes) {
List<Double> l = new ArrayList<>();
for (long i = 0; i < size; i++) {
l.add((double) i);
}
ls.add(l);
}
List<Function<Integer, Node.Builder<Double>>> ms = Arrays.asList(
s -> Nodes.doubleBuilder(),
s -> Nodes.doubleBuilder(s)
);
Object[][] params = new Object[ls.size() * ms.size()][];
int i = 0;
for (List<Double> l : ls) {
for (Function<Integer, Node.Builder<Double>> m : ms) {
params[i++] = new Object[]{l, m};
}
}
return params;
}
@Test(dataProvider = "Node.Builder<Double>")
public void testDoubleIteration(List<Double> l, Function<Integer, Node.Builder.OfDouble> m) {
Node.Builder.OfDouble nb = m.apply(l.size());
nb.begin(l.size());
for (Double i : l) {
nb.accept((double) i);
}
nb.end();
Node.OfDouble n = nb.build();
assertEquals(n.count(), l.size());
{
List<Double> _l = new ArrayList<>();
n.forEach((DoubleConsumer) _l::add);
assertContents(_l, l);
}
}
}

View file

@ -0,0 +1,155 @@
/*
* Copyright (c) 2012, 2017, 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.
*/
package java.util.stream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.SpliteratorTestHelper;
import java.util.function.Function;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
@Test
public class NodeTest extends OpTestCase {
@DataProvider(name = "nodes")
public Object[][] createSizes() {
List<Object[]> params = new ArrayList<>();
for (int size : Arrays.asList(0, 1, 4, 15, 16, 17, 127, 128, 129, 1000)) {
Integer[] array = new Integer[size];
for (int i = 0; i < array.length; i++) {
array[i] = i;
}
List<Node<Integer>> nodes = new ArrayList<>();
nodes.add(Nodes.node(array));
nodes.add(Nodes.node(Arrays.asList(array)));
nodes.add(degenerateTree(Arrays.asList(array).iterator()));
nodes.add(tree(Arrays.asList(array), l -> Nodes.node(l.toArray(new Integer[l.size()]))));
nodes.add(tree(Arrays.asList(array), l -> Nodes.node(l)));
nodes.add(fill(array, Nodes.builder(array.length, LambdaTestHelpers.integerArrayGenerator)));
nodes.add(fill(array, Nodes.builder()));
for (int i = 0; i < nodes.size(); i++) {
params.add(new Object[]{array, nodes.get(i)});
}
}
return params.toArray(new Object[0][]);
}
Node<Integer> fill(Integer[] array, Node.Builder<Integer> nb) {
nb.begin(array.length);
for (Integer i : array) {
nb.accept(i);
}
nb.end();
return nb.build();
}
Node<Integer> degenerateTree(Iterator<Integer> it) {
if (!it.hasNext()) {
return Nodes.node(Collections.emptyList());
}
Integer i = it.next();
if (it.hasNext()) {
return new Nodes.ConcNode<Integer>(Nodes.node(new Integer[] {i}), degenerateTree(it));
}
else {
return Nodes.node(new Integer[]{i});
}
}
Node<Integer> tree(List<Integer> l, Function<List<Integer>, Node<Integer>> m) {
if (l.size() < 3) {
return m.apply(l);
}
else {
return new Nodes.ConcNode<>(
tree(l.subList(0, l.size() / 2), m),
tree(l.subList(l.size() / 2, l.size()), m ));
}
}
@Test(dataProvider = "nodes")
public void testAsArray(Integer[] array, Node<Integer> n) {
assertEquals(n.asArray(LambdaTestHelpers.integerArrayGenerator), array);
}
@Test(dataProvider = "nodes")
public void testFlattenAsArray(Integer[] array, Node<Integer> n) {
assertEquals(Nodes.flatten(n, LambdaTestHelpers.integerArrayGenerator)
.asArray(LambdaTestHelpers.integerArrayGenerator), array);
}
@Test(dataProvider = "nodes")
public void testCopyTo(Integer[] array, Node<Integer> n) {
Integer[] copy = new Integer[(int) n.count()];
n.copyInto(copy, 0);
assertEquals(copy, array);
}
@Test(dataProvider = "nodes", groups = { "serialization-hostile" })
public void testForEach(Integer[] array, Node<Integer> n) {
List<Integer> l = new ArrayList<>((int) n.count());
n.forEach(e -> l.add(e));
assertEquals(l.toArray(), array);
}
@Test(dataProvider = "nodes")
public void testStreams(Integer[] array, Node<Integer> n) {
TestData<Integer, Stream<Integer>> data = TestData.Factory.ofRefNode("Node", n);
exerciseOps(data, s -> s);
exerciseTerminalOps(data, s -> s.toArray());
}
@Test(dataProvider = "nodes")
public void testSpliterator(Integer[] array, Node<Integer> n) {
SpliteratorTestHelper.testSpliterator(n::spliterator);
}
@Test(dataProvider = "nodes")
public void testTruncate(Integer[] array, Node<Integer> n) {
int[] nums = new int[] { 0, 1, array.length / 2, array.length - 1, array.length };
for (int start : nums)
for (int end : nums) {
if (start < 0 || end < 0 || end < start || end > array.length)
continue;
Node<Integer> slice = n.truncate(start, end, Integer[]::new);
Integer[] asArray = slice.asArray(Integer[]::new);
for (int k = start; k < end; k++)
assertEquals(array[k], asArray[k - start]);
}
}
}

View file

@ -0,0 +1,202 @@
/*
* Copyright (c) 2013, 2017, 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.
*/
package java.util.stream;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Spliterator;
import java.util.SpliteratorTestHelper;
import static java.util.stream.Collectors.toList;
import static org.testng.Assert.assertEquals;
/**
* @bug 8012987
*/
@Test
public class SliceSpliteratorTest extends LoggingTestCase {
static class UnorderedContentAsserter<T> implements SpliteratorTestHelper.ContentAsserter<T> {
Collection<T> source;
UnorderedContentAsserter(Collection<T> source) {
this.source = source;
}
@Override
public void assertContents(Collection<T> actual, Collection<T> expected, boolean isOrdered) {
if (isOrdered) {
assertEquals(actual, expected);
}
else {
assertEquals(actual.size(), expected.size());
assertTrue(source.containsAll(actual));
}
}
}
interface SliceTester {
void test(int size, int skip, int limit);
}
@DataProvider(name = "sliceSpliteratorDataProvider")
public static Object[][] sliceSpliteratorDataProvider() {
List<Object[]> data = new ArrayList<>();
// SIZED/SUBSIZED slice spliterator
{
SliceTester r = (size, skip, limit) -> {
final Collection<Integer> source = IntStream.range(0, size).boxed().collect(toList());
SpliteratorTestHelper.testSpliterator(() -> {
Spliterator<Integer> s = Arrays.spliterator(source.stream().toArray(Integer[]::new));
return new StreamSpliterators.SliceSpliterator.OfRef<>(s, skip, limit);
});
};
data.add(new Object[]{"StreamSpliterators.SliceSpliterator.OfRef", r});
}
{
SliceTester r = (size, skip, limit) -> {
final Collection<Integer> source = IntStream.range(0, size).boxed().collect(toList());
SpliteratorTestHelper.testIntSpliterator(() -> {
Spliterator.OfInt s = Arrays.spliterator(source.stream().mapToInt(i->i).toArray());
return new StreamSpliterators.SliceSpliterator.OfInt(s, skip, limit);
});
};
data.add(new Object[]{"StreamSpliterators.SliceSpliterator.OfInt", r});
}
{
SliceTester r = (size, skip, limit) -> {
final Collection<Long> source = LongStream.range(0, size).boxed().collect(toList());
SpliteratorTestHelper.testLongSpliterator(() -> {
Spliterator.OfLong s = Arrays.spliterator(source.stream().mapToLong(i->i).toArray());
return new StreamSpliterators.SliceSpliterator.OfLong(s, skip, limit);
});
};
data.add(new Object[]{"StreamSpliterators.SliceSpliterator.OfLong", r});
}
{
SliceTester r = (size, skip, limit) -> {
final Collection<Double> source = LongStream.range(0, size).asDoubleStream().boxed().collect(toList());
SpliteratorTestHelper.testDoubleSpliterator(() -> {
Spliterator.OfDouble s = Arrays.spliterator(source.stream().mapToDouble(i->i).toArray());
return new StreamSpliterators.SliceSpliterator.OfDouble(s, skip, limit);
});
};
data.add(new Object[]{"StreamSpliterators.SliceSpliterator.OfLong", r});
}
// Unordered slice spliterator
{
SliceTester r = (size, skip, limit) -> {
final Collection<Integer> source = IntStream.range(0, size).boxed().collect(toList());
final UnorderedContentAsserter<Integer> uca = new UnorderedContentAsserter<>(source);
SpliteratorTestHelper.testSpliterator(() -> {
Spliterator<Integer> s = Arrays.spliterator(source.stream().toArray(Integer[]::new));
return new StreamSpliterators.UnorderedSliceSpliterator.OfRef<>(s, skip, limit);
}, uca);
};
data.add(new Object[]{"StreamSpliterators.UnorderedSliceSpliterator.OfRef", r});
}
{
SliceTester r = (size, skip, limit) -> {
final Collection<Integer> source = IntStream.range(0, size).boxed().collect(toList());
final UnorderedContentAsserter<Integer> uca = new UnorderedContentAsserter<>(source);
SpliteratorTestHelper.testIntSpliterator(() -> {
Spliterator.OfInt s = Arrays.spliterator(source.stream().mapToInt(i->i).toArray());
return new StreamSpliterators.UnorderedSliceSpliterator.OfInt(s, skip, limit);
}, uca);
};
data.add(new Object[]{"StreamSpliterators.UnorderedSliceSpliterator.OfInt", r});
}
{
SliceTester r = (size, skip, limit) -> {
final Collection<Long> source = LongStream.range(0, size).boxed().collect(toList());
final UnorderedContentAsserter<Long> uca = new UnorderedContentAsserter<>(source);
SpliteratorTestHelper.testLongSpliterator(() -> {
Spliterator.OfLong s = Arrays.spliterator(source.stream().mapToLong(i->i).toArray());
return new StreamSpliterators.UnorderedSliceSpliterator.OfLong(s, skip, limit);
}, uca);
};
data.add(new Object[]{"StreamSpliterators.UnorderedSliceSpliterator.OfLong", r});
}
{
SliceTester r = (size, skip, limit) -> {
final Collection<Double> source = LongStream.range(0, size).asDoubleStream().boxed().collect(toList());
final UnorderedContentAsserter<Double> uca = new UnorderedContentAsserter<>(source);
SpliteratorTestHelper.testDoubleSpliterator(() -> {
Spliterator.OfDouble s = Arrays.spliterator(LongStream.range(0, SIZE).asDoubleStream().toArray());
return new StreamSpliterators.UnorderedSliceSpliterator.OfDouble(s, skip, limit);
}, uca);
};
data.add(new Object[]{"StreamSpliterators.UnorderedSliceSpliterator.OfLong", r});
}
return data.toArray(new Object[0][]);
}
static final int SIZE = 256;
static final int STEP = 32;
@Test(dataProvider = "sliceSpliteratorDataProvider")
public void testSliceSpliterator(String description, SliceTester r) {
setContext("size", SIZE);
for (int skip = 0; skip < SIZE; skip += STEP) {
setContext("skip", skip);
for (int limit = 0; limit < SIZE; limit += STEP) {
setContext("limit", skip);
r.test(SIZE, skip, limit);
}
}
}
}

View file

@ -0,0 +1,112 @@
/*
* Copyright (c) 2012, 2022, 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.
*/
package java.util.stream;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import java.util.*;
import java.util.function.DoubleConsumer;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
@Test
public class SpinedBufferDoubleTest extends AbstractSpinedBufferTest {
@DataProvider(name = "DoubleSpinedBuffer")
public Object[][] createDoubleSpinedBuffer() {
List<Object[]> params = new ArrayList<>();
for (int size : SIZES) {
// @@@ replace with double range when implemented
double[] array = LongStream.range(0, size).asDoubleStream().toArray();
SpinedBuffer.OfDouble sb = new SpinedBuffer.OfDouble();
Arrays.stream(array).forEach(sb);
params.add(new Object[]{array, sb});
}
return params.toArray(new Object[0][]);
}
@Test(dataProvider = "DoubleSpinedBuffer")
public void testDoubleSpliterator(double[] array, SpinedBuffer.OfDouble sb) {
assertEquals(sb.count(), array.length);
assertEquals(sb.count(), sb.spliterator().getExactSizeIfKnown());
SpliteratorTestHelper.testDoubleSpliterator(sb::spliterator);
}
@Test(dataProvider = "DoubleSpinedBuffer", groups = { "serialization-hostile" })
public void testLongLastSplit(double[] array, SpinedBuffer.OfDouble sb) {
Spliterator.OfDouble spliterator = sb.spliterator();
Spliterator.OfDouble split = spliterator.trySplit();
long splitSizes = (split == null) ? 0 : split.getExactSizeIfKnown();
long lastSplitSize = spliterator.getExactSizeIfKnown();
splitSizes += lastSplitSize;
assertEquals(splitSizes, array.length);
List<Double> contentOfLastSplit = new ArrayList<>();
spliterator.forEachRemaining((DoubleConsumer) contentOfLastSplit::add);
assertEquals(contentOfLastSplit.size(), lastSplitSize);
List<Double> end = Arrays.stream(array)
.boxed()
.skip(array.length - lastSplitSize)
.collect(Collectors.toList());
assertEquals(contentOfLastSplit, end);
}
@Test(groups = { "serialization-hostile" })
public void testDoubleSpinedBuffer() {
List<Double> list1 = new ArrayList<>();
List<Double> list2 = new ArrayList<>();
SpinedBuffer.OfDouble sb = new SpinedBuffer.OfDouble();
for (long i = 0; i < TEST_SIZE; i++) {
list1.add((double) i);
sb.accept((double) i);
}
PrimitiveIterator.OfDouble it = sb.iterator();
for (int i = 0; i < TEST_SIZE; i++) {
list2.add(it.nextDouble());
}
assertFalse(it.hasNext());
assertEquals(list1, list2);
for (int i = 0; i < TEST_SIZE; i++) {
assertEquals(sb.get(i), (double) i, Double.toString(i));
}
list2.clear();
sb.forEach((double i) -> list2.add(i));
assertEquals(list1, list2);
double[] array = sb.asPrimitiveArray();
list2.clear();
for (double i : array) {
list2.add(i);
}
assertEquals(list1, list2);
}
}

View file

@ -0,0 +1,111 @@
/*
* Copyright (c) 2012, 2022, 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.
*/
package java.util.stream;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import java.util.*;
import java.util.function.IntConsumer;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
@Test
public class SpinedBufferIntTest extends AbstractSpinedBufferTest {
@DataProvider(name = "IntSpinedBuffer")
public Object[][] createIntSpinedBuffer() {
List<Object[]> params = new ArrayList<>();
for (int size : SIZES) {
int[] array = IntStream.range(0, size).toArray();
SpinedBuffer.OfInt sb = new SpinedBuffer.OfInt();
Arrays.stream(array).forEach(sb);
params.add(new Object[]{array, sb});
}
return params.toArray(new Object[0][]);
}
@Test(dataProvider = "IntSpinedBuffer")
public void testIntSpliterator(int[] array, SpinedBuffer.OfInt sb) {
assertEquals(sb.count(), array.length);
assertEquals(sb.count(), sb.spliterator().getExactSizeIfKnown());
SpliteratorTestHelper.testIntSpliterator(sb::spliterator);
}
@Test(dataProvider = "IntSpinedBuffer", groups = { "serialization-hostile" })
public void testIntLastSplit(int[] array, SpinedBuffer.OfInt sb) {
Spliterator.OfInt spliterator = sb.spliterator();
Spliterator.OfInt split = spliterator.trySplit();
long splitSizes = (split == null) ? 0 : split.getExactSizeIfKnown();
long lastSplitSize = spliterator.getExactSizeIfKnown();
splitSizes += lastSplitSize;
assertEquals(splitSizes, array.length);
List<Integer> contentOfLastSplit = new ArrayList<>();
spliterator.forEachRemaining((IntConsumer) contentOfLastSplit::add);
assertEquals(contentOfLastSplit.size(), lastSplitSize);
List<Integer> end = Arrays.stream(array)
.boxed()
.skip(array.length - lastSplitSize)
.collect(Collectors.toList());
assertEquals(contentOfLastSplit, end);
}
@Test(groups = { "serialization-hostile" })
public void testIntSpinedBuffer() {
List<Integer> list1 = new ArrayList<>();
List<Integer> list2 = new ArrayList<>();
SpinedBuffer.OfInt sb = new SpinedBuffer.OfInt();
for (int i = 0; i < TEST_SIZE; i++) {
list1.add(i);
sb.accept(i);
}
PrimitiveIterator.OfInt it = sb.iterator();
for (int i = 0; i < TEST_SIZE; i++) {
list2.add(it.nextInt());
}
assertFalse(it.hasNext());
assertEquals(list1, list2);
for (int i = 0; i < TEST_SIZE; i++) {
assertEquals(sb.get(i), i, Integer.toString(i));
}
list2.clear();
sb.forEach((int i) -> list2.add(i));
assertEquals(list1, list2);
int[] array = sb.asPrimitiveArray();
list2.clear();
for (int i : array) {
list2.add(i);
}
assertEquals(list1, list2);
}
}

View file

@ -0,0 +1,122 @@
/*
* Copyright (c) 2012, 2013, 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.
*/
package java.util.stream;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import java.util.*;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
@Test
public class SpinedBufferIntegerTest extends AbstractSpinedBufferTest {
@DataProvider(name = "SpinedBuffer")
public Object[][] createSpinedBuffer() {
List<Object[]> params = new ArrayList<>();
for (int size : SIZES) {
int[] array = IntStream.range(0, size).toArray();
SpinedBuffer<Integer> sb = new SpinedBuffer<>();
Arrays.stream(array).boxed().forEach(sb);
params.add(new Object[]{array, sb});
sb = new SpinedBuffer<>(size / 2);
Arrays.stream(array).boxed().forEach(sb);
params.add(new Object[]{array, sb});
sb = new SpinedBuffer<>(size);
Arrays.stream(array).boxed().forEach(sb);
params.add(new Object[]{array, sb});
sb = new SpinedBuffer<>(size * 2);
Arrays.stream(array).boxed().forEach(sb);
params.add(new Object[]{array, sb});
}
return params.toArray(new Object[0][]);
}
@Test(dataProvider = "SpinedBuffer")
public void testSpliterator(int[] array, SpinedBuffer<Integer> sb) {
assertEquals(sb.count(), array.length);
assertEquals(sb.count(), sb.spliterator().getExactSizeIfKnown());
SpliteratorTestHelper.testSpliterator(sb::spliterator);
}
@Test(dataProvider = "SpinedBuffer", groups = { "serialization-hostile" })
public void testLastSplit(int[] array, SpinedBuffer<Integer> sb) {
Spliterator<Integer> spliterator = sb.spliterator();
Spliterator<Integer> split = spliterator.trySplit();
long splitSizes = (split == null) ? 0 : split.getExactSizeIfKnown();
long lastSplitSize = spliterator.getExactSizeIfKnown();
splitSizes += lastSplitSize;
assertEquals(splitSizes, array.length);
List<Integer> contentOfLastSplit = new ArrayList<>();
spliterator.forEachRemaining(contentOfLastSplit::add);
assertEquals(contentOfLastSplit.size(), lastSplitSize);
List<Integer> end = Arrays.stream(array)
.boxed()
.skip(array.length - lastSplitSize)
.collect(Collectors.toList());
assertEquals(contentOfLastSplit, end);
}
@Test(groups = { "serialization-hostile" })
public void testSpinedBuffer() {
List<Integer> list1 = new ArrayList<>();
List<Integer> list2 = new ArrayList<>();
SpinedBuffer<Integer> sb = new SpinedBuffer<>();
for (int i = 0; i < TEST_SIZE; i++) {
list1.add(i);
sb.accept(i);
}
Iterator<Integer> it = sb.iterator();
for (int i = 0; i < TEST_SIZE; i++) {
list2.add(it.next());
}
assertFalse(it.hasNext());
assertEquals(list1, list2);
for (int i = 0; i < TEST_SIZE; i++) {
assertEquals(sb.get(i), (Integer) i, Integer.toString(i));
}
list2.clear();
sb.forEach(list2::add);
assertEquals(list1, list2);
Integer[] array = sb.asArray(LambdaTestHelpers.integerArrayGenerator);
list2.clear();
for (Integer i : array) {
list2.add(i);
}
assertEquals(list1, list2);
}
}

View file

@ -0,0 +1,111 @@
/*
* Copyright (c) 2012, 2013, 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.
*/
package java.util.stream;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import java.util.*;
import java.util.function.LongConsumer;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
@Test
public class SpinedBufferLongTest extends AbstractSpinedBufferTest {
@DataProvider(name = "LongSpinedBuffer")
public Object[][] createLongSpinedBuffer() {
List<Object[]> params = new ArrayList<>();
for (int size : SIZES) {
long[] array = LongStream.range(0, size).toArray();
SpinedBuffer.OfLong sb = new SpinedBuffer.OfLong();
Arrays.stream(array).forEach(sb);
params.add(new Object[]{array, sb});
}
return params.toArray(new Object[0][]);
}
@Test(dataProvider = "LongSpinedBuffer")
public void testLongSpliterator(long[] array, SpinedBuffer.OfLong sb) {
assertEquals(sb.count(), array.length);
assertEquals(sb.count(), sb.spliterator().getExactSizeIfKnown());
SpliteratorTestHelper.testLongSpliterator(sb::spliterator);
}
@Test(dataProvider = "LongSpinedBuffer", groups = { "serialization-hostile" })
public void testLongLastSplit(long[] array, SpinedBuffer.OfLong sb) {
Spliterator.OfLong spliterator = sb.spliterator();
Spliterator.OfLong split = spliterator.trySplit();
long splitSizes = (split == null) ? 0 : split.getExactSizeIfKnown();
long lastSplitSize = spliterator.getExactSizeIfKnown();
splitSizes += lastSplitSize;
assertEquals(splitSizes, array.length);
List<Long> contentOfLastSplit = new ArrayList<>();
spliterator.forEachRemaining((LongConsumer) contentOfLastSplit::add);
assertEquals(contentOfLastSplit.size(), lastSplitSize);
List<Long> end = Arrays.stream(array)
.boxed()
.skip(array.length - lastSplitSize)
.collect(Collectors.toList());
assertEquals(contentOfLastSplit, end);
}
@Test(groups = { "serialization-hostile" })
public void testLongSpinedBuffer() {
List<Long> list1 = new ArrayList<>();
List<Long> list2 = new ArrayList<>();
SpinedBuffer.OfLong sb = new SpinedBuffer.OfLong();
for (long i = 0; i < TEST_SIZE; i++) {
list1.add(i);
sb.accept(i);
}
PrimitiveIterator.OfLong it = sb.iterator();
for (int i = 0; i < TEST_SIZE; i++) {
list2.add(it.nextLong());
}
assertFalse(it.hasNext());
assertEquals(list1, list2);
for (int i = 0; i < TEST_SIZE; i++) {
assertEquals(sb.get(i), i, Long.toString(i));
}
list2.clear();
sb.forEach((long i) -> list2.add(i));
assertEquals(list1, list2);
long[] array = sb.asPrimitiveArray();
list2.clear();
for (long i : array) {
list2.add(i);
}
assertEquals(list1, list2);
}
}

View file

@ -0,0 +1,96 @@
/*
* Copyright (c) 2012, 2013, 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.
*/
package java.util.stream;
import org.testng.annotations.Test;
import java.util.*;
import java.util.stream.Stream;
import java.util.stream.StreamOpFlag;
import java.util.stream.Streams;
import static java.util.stream.StreamOpFlag.*;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
/**
* StreamFlagsTest
*
* @author Brian Goetz
*/
@Test
public class StreamFlagsTest {
Stream<String> arrayList = new ArrayList<String>().stream();
Stream<String> linkedList = new LinkedList<String>().stream();
Stream<String> hashSet = new HashSet<String>().stream();
Stream<String> treeSet = new TreeSet<String>().stream();
Stream<String> linkedHashSet = new LinkedHashSet<String>().stream();
Stream<String> repeat = Stream.generate(() -> "");
Stream<?>[] streams = { arrayList, linkedList, hashSet, treeSet, linkedHashSet, repeat };
private void assertFlags(int value, EnumSet<StreamOpFlag> setFlags, EnumSet<StreamOpFlag> clearFlags) {
for (StreamOpFlag flag : setFlags)
assertTrue(flag.isKnown(value));
for (StreamOpFlag flag : clearFlags)
assertTrue(!flag.isKnown(value));
}
public void testBaseStreams() {
Stream<String> arrayList = new ArrayList<String>().stream();
Stream<String> linkedList = new LinkedList<String>().stream();
Stream<String> hashSet = new HashSet<String>().stream();
Stream<String> treeSet = new TreeSet<String>().stream();
Stream<String> linkedHashSet = new LinkedHashSet<String>().stream();
Stream<String> repeat = Stream.generate(() -> "");
assertFlags(OpTestCase.getStreamFlags(arrayList),
EnumSet.of(ORDERED, SIZED),
EnumSet.of(DISTINCT, SORTED, SHORT_CIRCUIT));
assertFlags(OpTestCase.getStreamFlags(linkedList),
EnumSet.of(ORDERED, SIZED),
EnumSet.of(DISTINCT, SORTED, SHORT_CIRCUIT));
assertFlags(OpTestCase.getStreamFlags(hashSet),
EnumSet.of(SIZED, DISTINCT),
EnumSet.of(ORDERED, SORTED, SHORT_CIRCUIT));
assertFlags(OpTestCase.getStreamFlags(treeSet),
EnumSet.of(ORDERED, SIZED, DISTINCT, SORTED),
EnumSet.of(SHORT_CIRCUIT));
assertFlags(OpTestCase.getStreamFlags(linkedHashSet),
EnumSet.of(ORDERED, DISTINCT, SIZED),
EnumSet.of(SORTED, SHORT_CIRCUIT));
assertFlags(OpTestCase.getStreamFlags(repeat),
EnumSet.noneOf(StreamOpFlag.class),
EnumSet.of(DISTINCT, SORTED, SHORT_CIRCUIT));
}
public void testFilter() {
for (Stream<?> s : streams) {
int baseFlags = OpTestCase.getStreamFlags(s);
int filteredFlags = OpTestCase.getStreamFlags(s.filter((Object e) -> true));
int expectedFlags = baseFlags & ~SIZED.set();
assertEquals(filteredFlags, expectedFlags);
}
}
}

View file

@ -0,0 +1,386 @@
/*
* Copyright (c) 2012, 2025, 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.
*/
package java.util.stream;
import org.testng.annotations.Test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.EnumSet;
import java.util.List;
import java.util.Spliterator;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.ToDoubleFunction;
import java.util.function.ToIntFunction;
import java.util.function.ToLongFunction;
import static java.util.stream.Collectors.toList;
import static java.util.stream.StreamOpFlag.*;
import static org.testng.Assert.*;
import static org.testng.Assert.assertEquals;
@Test
public class StreamOpFlagsTest {
public void testNullCombine() {
int sourceFlags = StreamOpFlag.IS_SIZED;
assertEquals(sourceFlags, toStreamFlags(combineOpFlags(sourceFlags, StreamOpFlag.INITIAL_OPS_VALUE)));
}
public void testInitialOpFlagsFromSourceFlags() {
List<StreamOpFlag> flags = new ArrayList<>(StreamOpFlagTestHelper.allStreamFlags());
for (int i = 0; i < (1 << flags.size()); i++) {
int sourceFlags = 0;
for (int f = 0; f < flags.size(); f++) {
if ((i & (1 << f)) != 0) {
sourceFlags |= flags.get(f).set();
}
}
int opsFlags = combineOpFlags(sourceFlags, StreamOpFlag.INITIAL_OPS_VALUE);
assertEquals(opsFlags, (~(sourceFlags << 1)) & StreamOpFlag.INITIAL_OPS_VALUE);
}
}
public void testSameCombine() {
for (StreamOpFlag f : StreamOpFlagTestHelper.allStreamFlags()) {
int sourceFlags = f.set();
int opsFlags;
opsFlags = combineOpFlags(sourceFlags, StreamOpFlag.INITIAL_OPS_VALUE);
opsFlags = combineOpFlags(f.set(), opsFlags);
assertEquals(sourceFlags, toStreamFlags(opsFlags));
}
}
public void testOpClear() {
for (StreamOpFlag f : StreamOpFlagTestHelper.allStreamFlags()) {
// Clear when source not set
int sourceFlags = 0;
int opsFlags;
opsFlags = combineOpFlags(sourceFlags, StreamOpFlag.INITIAL_OPS_VALUE);
opsFlags = combineOpFlags(f.clear(), opsFlags);
assertEquals(sourceFlags, toStreamFlags(opsFlags));
// Clear when source set
sourceFlags = f.set();
opsFlags = combineOpFlags(sourceFlags, StreamOpFlag.INITIAL_OPS_VALUE);
opsFlags = combineOpFlags(f.clear(), opsFlags);
assertEquals(0, toStreamFlags(opsFlags));
}
}
public void testOpInject() {
for (StreamOpFlag f : StreamOpFlagTestHelper.allStreamFlags()) {
// Set when source not set
int sourceFlags = 0;
int opsFlags;
opsFlags = combineOpFlags(sourceFlags, StreamOpFlag.INITIAL_OPS_VALUE);
opsFlags = combineOpFlags(f.set(), opsFlags);
assertEquals(f.set(), toStreamFlags(opsFlags));
// Set when source set
sourceFlags = f.set();
opsFlags = combineOpFlags(sourceFlags, StreamOpFlag.INITIAL_OPS_VALUE);
opsFlags = combineOpFlags(f.set(), opsFlags);
assertEquals(sourceFlags, toStreamFlags(opsFlags));
}
}
public void testPairSet() {
List<Integer> sourceFlagsList
= StreamOpFlagTestHelper.allStreamFlags().stream().map(StreamOpFlag::set).collect(toList());
sourceFlagsList.add(0, 0);
for (int sourceFlags : sourceFlagsList) {
for (StreamOpFlag f1 : StreamOpFlagTestHelper.allStreamFlags()) {
for (StreamOpFlag f2 : StreamOpFlagTestHelper.allStreamFlags()) {
int opsFlags;
opsFlags = combineOpFlags(sourceFlags, StreamOpFlag.INITIAL_OPS_VALUE);
opsFlags = combineOpFlags(f1.set(), opsFlags);
opsFlags = combineOpFlags(f2.set(), opsFlags);
assertEquals(sourceFlags | f1.set() | f2.set(), toStreamFlags(opsFlags));
}
}
}
}
public void testPairSetAndClear() {
List<Integer> sourceFlagsList
= StreamOpFlagTestHelper.allStreamFlags().stream().map(StreamOpFlag::set).collect(toList());
sourceFlagsList.add(0, 0);
for (int sourceFlags : sourceFlagsList) {
for (StreamOpFlag f1 : StreamOpFlagTestHelper.allStreamFlags()) {
for (StreamOpFlag f2 : StreamOpFlagTestHelper.allStreamFlags()) {
int opsFlags;
opsFlags = combineOpFlags(sourceFlags, StreamOpFlag.INITIAL_OPS_VALUE);
opsFlags = combineOpFlags(f1.set(), opsFlags);
opsFlags = combineOpFlags(f2.clear(), opsFlags);
if (f1 == f2)
assertEquals((f2.set() == sourceFlags) ? 0 : sourceFlags, toStreamFlags(opsFlags));
else
assertEquals((f2.set() == sourceFlags) ? f1.set() : sourceFlags | f1.set(), toStreamFlags(opsFlags));
}
}
}
}
public void testShortCircuit() {
int opsFlags = combineOpFlags(0, StreamOpFlag.INITIAL_OPS_VALUE);
assertFalse(StreamOpFlag.SHORT_CIRCUIT.isKnown(opsFlags));
opsFlags = combineOpFlags(StreamOpFlag.IS_SHORT_CIRCUIT, opsFlags);
assertTrue(StreamOpFlag.SHORT_CIRCUIT.isKnown(opsFlags));
opsFlags = combineOpFlags(0, opsFlags);
assertTrue(StreamOpFlag.SHORT_CIRCUIT.isKnown(opsFlags));
}
public void testApplySourceFlags() {
int sourceFlags = StreamOpFlag.IS_SIZED | StreamOpFlag.IS_DISTINCT;
List<Integer> ops = Arrays.asList(StreamOpFlag.NOT_SIZED, StreamOpFlag.IS_ORDERED | StreamOpFlag.IS_SORTED);
int opsFlags = StreamOpFlag.combineOpFlags(sourceFlags, StreamOpFlag.INITIAL_OPS_VALUE);
for (int opFlags : ops) {
opsFlags = combineOpFlags(opFlags, opsFlags);
}
assertFalse(StreamOpFlag.SIZED.isKnown(opsFlags));
assertTrue(StreamOpFlag.SIZED.isCleared(opsFlags));
assertFalse(StreamOpFlag.SIZED.isPreserved(opsFlags));
assertTrue(StreamOpFlag.DISTINCT.isKnown(opsFlags));
assertFalse(StreamOpFlag.DISTINCT.isCleared(opsFlags));
assertFalse(StreamOpFlag.DISTINCT.isPreserved(opsFlags));
assertTrue(StreamOpFlag.SORTED.isKnown(opsFlags));
assertFalse(StreamOpFlag.SORTED.isCleared(opsFlags));
assertFalse(StreamOpFlag.SORTED.isPreserved(opsFlags));
assertTrue(StreamOpFlag.ORDERED.isKnown(opsFlags));
assertFalse(StreamOpFlag.ORDERED.isCleared(opsFlags));
assertFalse(StreamOpFlag.ORDERED.isPreserved(opsFlags));
int streamFlags = toStreamFlags(opsFlags);
assertFalse(StreamOpFlag.SIZED.isKnown(streamFlags));
assertTrue(StreamOpFlag.DISTINCT.isKnown(streamFlags));
assertTrue(StreamOpFlag.SORTED.isKnown(streamFlags));
assertTrue(StreamOpFlag.ORDERED.isKnown(streamFlags));
}
public void testSpliteratorMask() {
assertSpliteratorMask(StreamOpFlag.DISTINCT.set(), StreamOpFlag.IS_DISTINCT);
assertSpliteratorMask(StreamOpFlag.DISTINCT.clear(), 0);
assertSpliteratorMask(StreamOpFlag.SORTED.set(), StreamOpFlag.IS_SORTED);
assertSpliteratorMask(StreamOpFlag.SORTED.clear(), 0);
assertSpliteratorMask(StreamOpFlag.ORDERED.set(), StreamOpFlag.IS_ORDERED);
assertSpliteratorMask(StreamOpFlag.ORDERED.clear(), 0);
assertSpliteratorMask(StreamOpFlag.SIZED.set(), StreamOpFlag.IS_SIZED);
assertSpliteratorMask(StreamOpFlag.SIZED.clear(), 0);
assertSpliteratorMask(StreamOpFlag.SHORT_CIRCUIT.set(), 0);
assertSpliteratorMask(StreamOpFlag.SHORT_CIRCUIT.clear(), 0);
}
private void assertSpliteratorMask(int actual, int expected) {
assertEquals(actual & StreamOpFlag.SPLITERATOR_CHARACTERISTICS_MASK, expected);
}
public void testStreamMask() {
assertStreamMask(StreamOpFlag.DISTINCT.set(), StreamOpFlag.IS_DISTINCT);
assertStreamMask(StreamOpFlag.DISTINCT.clear(), 0);
assertStreamMask(StreamOpFlag.SORTED.set(), StreamOpFlag.IS_SORTED);
assertStreamMask(StreamOpFlag.SORTED.clear(), 0);
assertStreamMask(StreamOpFlag.ORDERED.set(), StreamOpFlag.IS_ORDERED);
assertStreamMask(StreamOpFlag.ORDERED.clear(), 0);
assertStreamMask(StreamOpFlag.SIZED.set(), StreamOpFlag.IS_SIZED);
assertStreamMask(StreamOpFlag.SIZED.clear(), 0);
assertStreamMask(StreamOpFlag.SHORT_CIRCUIT.set(), 0);
assertStreamMask(StreamOpFlag.SHORT_CIRCUIT.clear(), 0);
}
private void assertStreamMask(int actual, int expected) {
assertEquals(actual & StreamOpFlag.STREAM_MASK, expected);
}
public void testOpMask() {
assertOpMask(StreamOpFlag.DISTINCT.set(), StreamOpFlag.IS_DISTINCT);
assertOpMask(StreamOpFlag.DISTINCT.clear(), StreamOpFlag.NOT_DISTINCT);
assertOpMask(StreamOpFlag.SORTED.set(), StreamOpFlag.IS_SORTED);
assertOpMask(StreamOpFlag.SORTED.clear(), StreamOpFlag.NOT_SORTED);
assertOpMask(StreamOpFlag.ORDERED.set(), StreamOpFlag.IS_ORDERED);
assertOpMask(StreamOpFlag.ORDERED.clear(), StreamOpFlag.NOT_ORDERED);
assertOpMask(StreamOpFlag.SIZED.set(), 0);
assertOpMask(StreamOpFlag.SIZED.clear(), StreamOpFlag.NOT_SIZED);
assertOpMask(StreamOpFlag.SHORT_CIRCUIT.set(), StreamOpFlag.IS_SHORT_CIRCUIT);
assertOpMask(StreamOpFlag.SHORT_CIRCUIT.clear(), 0);
}
private void assertOpMask(int actual, int expected) {
assertEquals(actual & StreamOpFlag.OP_MASK, expected);
}
public void testTerminalOpMask() {
assertTerminalOpMask(StreamOpFlag.DISTINCT.set(), 0);
assertTerminalOpMask(StreamOpFlag.DISTINCT.clear(), 0);
assertTerminalOpMask(StreamOpFlag.SORTED.set(), 0);
assertTerminalOpMask(StreamOpFlag.SORTED.clear(), 0);
assertTerminalOpMask(StreamOpFlag.ORDERED.set(), 0);
assertTerminalOpMask(StreamOpFlag.ORDERED.clear(), StreamOpFlag.NOT_ORDERED);
assertTerminalOpMask(StreamOpFlag.SIZED.set(), 0);
assertTerminalOpMask(StreamOpFlag.SIZED.clear(), 0);
assertTerminalOpMask(StreamOpFlag.SHORT_CIRCUIT.set(), StreamOpFlag.IS_SHORT_CIRCUIT);
assertTerminalOpMask(StreamOpFlag.SHORT_CIRCUIT.clear(), 0);
}
private void assertTerminalOpMask(int actual, int expected) {
assertEquals(actual & StreamOpFlag.TERMINAL_OP_MASK, expected);
}
public void testUpstreamTerminalOpMask() {
assertUpstreamTerminalOpMask(StreamOpFlag.DISTINCT.set(), 0);
assertUpstreamTerminalOpMask(StreamOpFlag.DISTINCT.clear(), 0);
assertUpstreamTerminalOpMask(StreamOpFlag.SORTED.set(), 0);
assertUpstreamTerminalOpMask(StreamOpFlag.SORTED.clear(), 0);
assertUpstreamTerminalOpMask(StreamOpFlag.ORDERED.set(), 0);
assertUpstreamTerminalOpMask(StreamOpFlag.ORDERED.clear(), StreamOpFlag.NOT_ORDERED);
assertUpstreamTerminalOpMask(StreamOpFlag.SIZED.set(), 0);
assertUpstreamTerminalOpMask(StreamOpFlag.SIZED.clear(), 0);
assertUpstreamTerminalOpMask(StreamOpFlag.SHORT_CIRCUIT.set(), 0);
assertUpstreamTerminalOpMask(StreamOpFlag.SHORT_CIRCUIT.clear(), 0);
}
private void assertUpstreamTerminalOpMask(int actual, int expected) {
assertEquals(actual & StreamOpFlag.UPSTREAM_TERMINAL_OP_MASK, expected);
}
public void testSpliteratorCharacteristics() {
assertEquals(Spliterator.DISTINCT, StreamOpFlag.IS_DISTINCT);
assertEquals(Spliterator.SORTED, StreamOpFlag.IS_SORTED);
assertEquals(Spliterator.ORDERED, StreamOpFlag.IS_ORDERED);
assertEquals(Spliterator.SIZED, StreamOpFlag.IS_SIZED);
List<Integer> others = Arrays.asList(Spliterator.NONNULL, Spliterator.IMMUTABLE,
Spliterator.CONCURRENT, Spliterator.SUBSIZED);
for (int c : others) {
assertNotEquals(c, StreamOpFlag.IS_SHORT_CIRCUIT);
}
}
public void testSpliteratorCharacteristicsMask() {
assertSpliteratorCharacteristicsMask(StreamOpFlag.DISTINCT.set(), StreamOpFlag.IS_DISTINCT);
assertSpliteratorCharacteristicsMask(StreamOpFlag.DISTINCT.clear(), 0);
assertSpliteratorCharacteristicsMask(StreamOpFlag.SORTED.set(), StreamOpFlag.IS_SORTED);
assertSpliteratorCharacteristicsMask(StreamOpFlag.SORTED.clear(), 0);
assertSpliteratorCharacteristicsMask(StreamOpFlag.ORDERED.set(), StreamOpFlag.IS_ORDERED);
assertSpliteratorCharacteristicsMask(StreamOpFlag.ORDERED.clear(), 0);
assertSpliteratorCharacteristicsMask(StreamOpFlag.SIZED.set(), StreamOpFlag.IS_SIZED);
assertSpliteratorCharacteristicsMask(StreamOpFlag.SIZED.clear(), 0);
assertSpliteratorCharacteristicsMask(StreamOpFlag.SHORT_CIRCUIT.set(), 0);
assertSpliteratorCharacteristicsMask(StreamOpFlag.SHORT_CIRCUIT.clear(), 0);
}
private void assertSpliteratorCharacteristicsMask(int actual, int expected) {
assertEquals(StreamOpFlag.fromCharacteristics(actual), expected);
}
public void testSpliteratorSorted() {
class SortedEmptySpliterator<T extends Comparable<? super T>> implements Spliterator<T> {
final Comparator<T> c;
SortedEmptySpliterator(Comparator<T> c) {
this.c = c;
}
@Override
public Spliterator<T> trySplit() {
return null;
}
@Override
public boolean tryAdvance(Consumer<? super T> action) {
return false;
}
@Override
public long estimateSize() {
return Long.MAX_VALUE;
}
@Override
public int characteristics() {
return Spliterator.SORTED;
}
@Override
public Comparator<? super T> getComparator() {
return c;
}
}
{
int flags = StreamOpFlag.fromCharacteristics(new SortedEmptySpliterator<>(null));
assertEquals(flags, StreamOpFlag.IS_SORTED);
}
{
int flags = StreamOpFlag.fromCharacteristics(new SortedEmptySpliterator<>((a, b) -> 0));
assertEquals(flags, 0);
}
{
int flags = StreamOpFlag.fromCharacteristics(new SortedEmptySpliterator<String>(Comparator.naturalOrder()));
assertEquals(flags, StreamOpFlag.IS_SORTED);
}
}
}

View file

@ -0,0 +1,441 @@
/*
* Copyright (c) 2012, 2013, 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.
*/
package java.util.stream;
import org.testng.annotations.Test;
import java.util.function.Function;
import static org.testng.Assert.fail;
/**
* StreamReuseTest
*
* @author Brian Goetz
*/
@Test
public class StreamReuseTest {
private <T, U, E, S extends BaseStream<E, S>, D extends TestData<E, S>> void assertSecondFails(
D data,
Function<S, T> first,
Function<S, U> second,
Class<? extends Throwable> exception,
String text) {
S stream = data.stream();
T fr = first.apply(stream);
try {
U sr = second.apply(stream);
fail(text + " (seq)");
}
catch (Throwable e) {
if (exception.isAssignableFrom(e.getClass())) {
// Expected
}
else if (e instanceof Error)
throw (Error) e;
else if (e instanceof RuntimeException)
throw (RuntimeException) e;
else
throw new AssertionError("Unexpected exception " + e.getClass(), e);
}
stream = data.parallelStream();
fr = first.apply(stream);
try {
U sr = second.apply(stream);
fail(text + " (par)");
}
catch (Throwable e) {
if (exception.isAssignableFrom(e.getClass())) {
// Expected
}
else if (e instanceof Error)
throw (Error) e;
else if (e instanceof RuntimeException)
throw (RuntimeException) e;
else
throw new AssertionError("Unexpected exception " + e.getClass(), e);
}
}
// Stream
@Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
public void testTwoStreams(String name, TestData<Integer, Stream<Integer>> data) {
assertSecondFails(data,
(Stream<Integer> s) -> s.map(i -> i), (Stream<Integer> s) -> s.map(i -> i),
IllegalStateException.class,
"Stream map / map succeeded erroneously");
assertSecondFails(data,
Stream::distinct, (Stream<Integer> s) -> s.map(i -> i),
IllegalStateException.class,
"Stream distinct / map succeeded erroneously");
assertSecondFails(data,
(Stream<Integer> s) -> s.map(i -> i), Stream::distinct,
IllegalStateException.class,
"Stream map / distinct succeeded erroneously");
assertSecondFails(data,
Stream::distinct, Stream::distinct,
IllegalStateException.class,
"Stream distinct / distinct succeeded erroneously");
}
@Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
public void testTwoTerminals(String name, TestData<Integer, Stream<Integer>> data) {
assertSecondFails(data,
Stream::findFirst, Stream::findFirst,
IllegalStateException.class,
"Stream findFirst / findFirst succeeded erroneously");
}
@Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
public void testTerminalStream(String name, TestData<Integer, Stream<Integer>> data) {
assertSecondFails(data,
Stream::findFirst, (Stream<Integer> s) -> s.map(i -> i),
IllegalStateException.class,
"Stream findFirst / map succeeded erroneously");
assertSecondFails(data,
(Stream<Integer> s) -> s.map(i -> i), Stream::findFirst,
IllegalStateException.class,
"Stream map / findFirst succeeded erroneously");
assertSecondFails(data,
Stream::findFirst, Stream::distinct,
IllegalStateException.class,
"Stream findFirst / distinct succeeded erroneously");
assertSecondFails(data,
Stream::distinct, Stream::findFirst,
IllegalStateException.class,
"Stream distinct / findFirst succeeded erroneously");
}
@Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
public void testTwoIterators(String name, TestData<Integer, Stream<Integer>> data) {
assertSecondFails(data,
Stream::iterator, Stream::iterator,
IllegalStateException.class,
"Stream iterator / iterator succeeded erroneously");
}
@Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
public void testTerminalIterator(String name, TestData<Integer, Stream<Integer>> data) {
assertSecondFails(data,
Stream::iterator, Stream::findFirst,
IllegalStateException.class,
"Stream iterator / findFirst succeeded erroneously");
assertSecondFails(data,
Stream::findFirst, Stream::iterator,
IllegalStateException.class,
"Stream findFirst / iterator succeeded erroneously");
}
@Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
public void testStreamIterator(String name, TestData<Integer, Stream<Integer>> data) {
assertSecondFails(data,
Stream::iterator, (Stream<Integer> s) -> s.map(i -> i),
IllegalStateException.class,
"Stream iterator / map succeeded erroneously");
assertSecondFails(data,
(Stream<Integer> s) -> s.map(i -> i), Stream::iterator,
IllegalStateException.class,
"Stream map / iterator succeeded erroneously");
assertSecondFails(data,
Stream::iterator, Stream::distinct,
IllegalStateException.class,
"Stream iterator / distinct succeeded erroneously");
assertSecondFails(data,
Stream::distinct, Stream::iterator,
IllegalStateException.class,
"Stream distinct / iterator succeeded erroneously");
}
// IntStream
@Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
public void testTwoStreams(String name, TestData.OfInt data) {
assertSecondFails(data,
(IntStream s) -> s.mapToObj(i -> i), (IntStream s) -> s.mapToObj(i -> i),
IllegalStateException.class,
"IntStream map / map succeeded erroneously");
assertSecondFails(data,
IntStream::distinct, (IntStream s) -> s.mapToObj(i -> i),
IllegalStateException.class,
"IntStream distinct / map succeeded erroneously");
assertSecondFails(data,
(IntStream s) -> s.mapToObj(i -> i), IntStream::distinct,
IllegalStateException.class,
"IntStream map / distinct succeeded erroneously");
assertSecondFails(data,
IntStream::distinct, IntStream::distinct,
IllegalStateException.class,
"IntStream distinct / distinct succeeded erroneously");
}
@Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
public void testTwoTerminals(String name, TestData.OfInt data) {
assertSecondFails(data,
IntStream::sum, IntStream::sum,
IllegalStateException.class,
"IntStream sum / sum succeeded erroneously");
}
@Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
public void testTerminalStream(String name, TestData.OfInt data) {
assertSecondFails(data,
IntStream::sum, (IntStream s) -> s.mapToObj(i -> i),
IllegalStateException.class,
"IntStream sum / map succeeded erroneously");
assertSecondFails(data,
(IntStream s) -> s.mapToObj(i -> i), IntStream::sum,
IllegalStateException.class,
"IntStream map / sum succeeded erroneously");
assertSecondFails(data,
IntStream::sum, IntStream::distinct,
IllegalStateException.class,
"IntStream sum / distinct succeeded erroneously");
assertSecondFails(data,
IntStream::distinct, IntStream::sum,
IllegalStateException.class,
"IntStream distinct / sum succeeded erroneously");
}
@Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
public void testTwoIterators(String name, TestData.OfInt data) {
assertSecondFails(data,
IntStream::iterator, IntStream::iterator,
IllegalStateException.class,
"IntStream iterator / iterator succeeded erroneously");
}
@Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
public void testTerminalIterator(String name, TestData.OfInt data) {
assertSecondFails(data,
IntStream::iterator, IntStream::sum,
IllegalStateException.class,
"IntStream iterator / sum succeeded erroneously");
assertSecondFails(data,
IntStream::sum, IntStream::iterator,
IllegalStateException.class,
"Stream sum / iterator succeeded erroneously");
}
@Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
public void testStreamIterator(String name, TestData.OfInt data) {
assertSecondFails(data,
IntStream::iterator, (IntStream s) -> s.mapToObj(i -> i),
IllegalStateException.class,
"IntStream iterator / map succeeded erroneously");
assertSecondFails(data,
(IntStream s) -> s.mapToObj(i -> i), IntStream::iterator,
IllegalStateException.class,
"IntStream map / iterator succeeded erroneously");
assertSecondFails(data,
IntStream::iterator, IntStream::distinct,
IllegalStateException.class,
"IntStream iterator / distinct succeeded erroneously");
assertSecondFails(data,
IntStream::distinct, IntStream::iterator,
IllegalStateException.class,
"IntStream distinct / iterator succeeded erroneously");
}
// LongStream
@Test(dataProvider = "LongStreamTestData", dataProviderClass = LongStreamTestDataProvider.class)
public void testTwoStreams(String name, TestData.OfLong data) {
assertSecondFails(data,
(LongStream s) -> s.mapToObj(i -> i), (LongStream s) -> s.mapToObj(i -> i),
IllegalStateException.class,
"LongStream map / map succeeded erroneously");
assertSecondFails(data,
LongStream::distinct, (LongStream s) -> s.mapToObj(i -> i),
IllegalStateException.class,
"LongStream distinct / map succeeded erroneously");
assertSecondFails(data,
(LongStream s) -> s.mapToObj(i -> i), LongStream::distinct,
IllegalStateException.class,
"LongStream map / distinct succeeded erroneously");
assertSecondFails(data,
LongStream::distinct, LongStream::distinct,
IllegalStateException.class,
"LongStream distinct / distinct succeeded erroneously");
}
@Test(dataProvider = "LongStreamTestData", dataProviderClass = LongStreamTestDataProvider.class)
public void testTwoTerminals(String name, TestData.OfLong data) {
assertSecondFails(data,
LongStream::sum, LongStream::sum,
IllegalStateException.class,
"LongStream sum / sum succeeded erroneously");
}
@Test(dataProvider = "LongStreamTestData", dataProviderClass = LongStreamTestDataProvider.class)
public void testTerminalStream(String name, TestData.OfLong data) {
assertSecondFails(data,
LongStream::sum, (LongStream s) -> s.mapToObj(i -> i),
IllegalStateException.class,
"LongStream sum / map succeeded erroneously");
assertSecondFails(data,
(LongStream s) -> s.mapToObj(i -> i), LongStream::sum,
IllegalStateException.class,
"LongStream map / sum succeeded erroneously");
assertSecondFails(data,
LongStream::sum, LongStream::distinct,
IllegalStateException.class,
"LongStream sum / distinct succeeded erroneously");
assertSecondFails(data,
LongStream::distinct, LongStream::sum,
IllegalStateException.class,
"LongStream distinct / sum succeeded erroneously");
}
@Test(dataProvider = "LongStreamTestData", dataProviderClass = LongStreamTestDataProvider.class)
public void testTwoIterators(String name, TestData.OfLong data) {
assertSecondFails(data,
LongStream::iterator, LongStream::iterator,
IllegalStateException.class,
"LongStream iterator / iterator succeeded erroneously");
}
@Test(dataProvider = "LongStreamTestData", dataProviderClass = LongStreamTestDataProvider.class)
public void testTerminalIterator(String name, TestData.OfLong data) {
assertSecondFails(data,
LongStream::iterator, LongStream::sum,
IllegalStateException.class,
"LongStream iterator / sum succeeded erroneously");
assertSecondFails(data,
LongStream::sum, LongStream::iterator,
IllegalStateException.class,
"Stream sum / iterator succeeded erroneously");
}
@Test(dataProvider = "LongStreamTestData", dataProviderClass = LongStreamTestDataProvider.class)
public void testStreamIterator(String name, TestData.OfLong data) {
assertSecondFails(data,
LongStream::iterator, (LongStream s) -> s.mapToObj(i -> i),
IllegalStateException.class,
"LongStream iterator / map succeeded erroneously");
assertSecondFails(data,
(LongStream s) -> s.mapToObj(i -> i), LongStream::iterator,
IllegalStateException.class,
"LongStream map / iterator succeeded erroneously");
assertSecondFails(data,
LongStream::iterator, LongStream::distinct,
IllegalStateException.class,
"LongStream iterator / distinct succeeded erroneously");
assertSecondFails(data,
LongStream::distinct, LongStream::iterator,
IllegalStateException.class,
"LongStream distinct / iterator succeeded erroneously");
}
// DoubleStream
@Test(dataProvider = "DoubleStreamTestData", dataProviderClass = DoubleStreamTestDataProvider.class)
public void testTwoStreams(String name, TestData.OfDouble data) {
assertSecondFails(data,
(DoubleStream s) -> s.mapToObj(i -> i), (DoubleStream s) -> s.mapToObj(i -> i),
IllegalStateException.class,
"DoubleStream map / map succeeded erroneously");
assertSecondFails(data,
DoubleStream::distinct, (DoubleStream s) -> s.mapToObj(i -> i),
IllegalStateException.class,
"DoubleStream distinct / map succeeded erroneously");
assertSecondFails(data,
(DoubleStream s) -> s.mapToObj(i -> i), DoubleStream::distinct,
IllegalStateException.class,
"DoubleStream map / distinct succeeded erroneously");
assertSecondFails(data,
DoubleStream::distinct, DoubleStream::distinct,
IllegalStateException.class,
"DoubleStream distinct / distinct succeeded erroneously");
}
@Test(dataProvider = "DoubleStreamTestData", dataProviderClass = DoubleStreamTestDataProvider.class)
public void testTwoTerminals(String name, TestData.OfDouble data) {
assertSecondFails(data,
DoubleStream::sum, DoubleStream::sum,
IllegalStateException.class,
"DoubleStream sum / sum succeeded erroneously");
}
@Test(dataProvider = "DoubleStreamTestData", dataProviderClass = DoubleStreamTestDataProvider.class)
public void testTerminalStream(String name, TestData.OfDouble data) {
assertSecondFails(data,
DoubleStream::sum, (DoubleStream s) -> s.mapToObj(i -> i),
IllegalStateException.class,
"DoubleStream sum / map succeeded erroneously");
assertSecondFails(data,
(DoubleStream s) -> s.mapToObj(i -> i), DoubleStream::sum,
IllegalStateException.class,
"DoubleStream map / sum succeeded erroneously");
assertSecondFails(data,
DoubleStream::sum, DoubleStream::distinct,
IllegalStateException.class,
"DoubleStream sum / distinct succeeded erroneously");
assertSecondFails(data,
DoubleStream::distinct, DoubleStream::sum,
IllegalStateException.class,
"DoubleStream distinct / sum succeeded erroneously");
}
@Test(dataProvider = "DoubleStreamTestData", dataProviderClass = DoubleStreamTestDataProvider.class)
public void testTwoIterators(String name, TestData.OfDouble data) {
assertSecondFails(data,
DoubleStream::iterator, DoubleStream::iterator,
IllegalStateException.class,
"DoubleStream iterator / iterator succeeded erroneously");
}
@Test(dataProvider = "DoubleStreamTestData", dataProviderClass = DoubleStreamTestDataProvider.class)
public void testTerminalIterator(String name, TestData.OfDouble data) {
assertSecondFails(data,
DoubleStream::iterator, DoubleStream::sum,
IllegalStateException.class,
"DoubleStream iterator / sum succeeded erroneously");
assertSecondFails(data,
DoubleStream::sum, DoubleStream::iterator,
IllegalStateException.class,
"Stream sum / iterator succeeded erroneously");
}
@Test(dataProvider = "DoubleStreamTestData", dataProviderClass = DoubleStreamTestDataProvider.class)
public void testStreamIterator(String name, TestData.OfDouble data) {
assertSecondFails(data,
DoubleStream::iterator, (DoubleStream s) -> s.mapToObj(i -> i),
IllegalStateException.class,
"DoubleStream iterator / map succeeded erroneously");
assertSecondFails(data,
(DoubleStream s) -> s.mapToObj(i -> i), DoubleStream::iterator,
IllegalStateException.class,
"DoubleStream map / iterator succeeded erroneously");
assertSecondFails(data,
DoubleStream::iterator, DoubleStream::distinct,
IllegalStateException.class,
"DoubleStream iterator / distinct succeeded erroneously");
assertSecondFails(data,
DoubleStream::distinct, DoubleStream::iterator,
IllegalStateException.class,
"DoubleStream distinct / iterator succeeded erroneously");
}
}

View file

@ -0,0 +1 @@
timeout.default.seconds=480

View file

@ -0,0 +1,72 @@
/*
* Copyright (c) 2021, 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.
*/
import org.testng.annotations.Test;
import java.util.List;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static org.testng.Assert.assertEquals;
/*
* THE CONTENTS OF THIS FILE HAVE TO BE IN SYNC WITH THE EXAMPLES USED IN THE JAVADOC.
*
* @test
* @run testng/othervm JavadocExamples
* @summary Checks to ensure example code displayed in the API documentation of
* java/util/Stream compiles correctly.
*/
public class JavadocExamples {
// From mapMulti
@Test
public void testNumberIntegerExample() {
Stream<Number> numbers = Stream.of(1, 2, 3.0);
List<Integer> integers = numbers.<Integer>mapMulti((number, consumer) -> {
if (number instanceof Integer i)
consumer.accept(i);
})
.collect(Collectors.toList());
assertEquals(integers, List.of(1,2));
}
@Test
public void testExpandIterableExample() {
var nestedList = List.of(1, List.of(2, List.of(3, 4)), 5);
Stream<Object> expandedStream = nestedList.stream().mapMulti(C::expandIterable);
assertEquals(expandedStream.toList(), List.of(1,2,3,4,5));
}
static class C {
static void expandIterable(Object e, Consumer<Object> c) {
if (e instanceof Iterable<?> elements) {
for (Object ie : elements) {
expandIterable(ie, c);
}
} else if (e != null) {
c.accept(e);
}
}
}
}

View file

@ -0,0 +1,8 @@
# This file identifies root(s) of the test-ng hierarchy.
TestNG.dirs = .
lib.dirs = /lib/testlibrary/bootlib
# Tests that must run in othervm mode
othervm.dirs= /java/util/stream

View file

@ -0,0 +1,87 @@
/*
* Copyright (c) 2012, 2013, 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.
*/
package org.openjdk.tests.java.lang.invoke;
import org.testng.annotations.Test;
import java.io.Serializable;
import java.lang.invoke.SerializedLambda;
import java.lang.reflect.Method;
import static org.testng.Assert.fail;
/**
* Ensure that the $deserializeLambda$ method is present when it should be, and absent otherwise
*/
@Test(groups = { "serialization-hostile" })
public class DeserializeMethodTest {
private void assertDeserializeMethod(Class<?> clazz, boolean expectedPresent) {
try {
Method m = clazz.getDeclaredMethod("$deserializeLambda$", SerializedLambda.class);
if (!expectedPresent)
fail("Unexpected $deserializeLambda$ in " + clazz);
}
catch (NoSuchMethodException e) {
if (expectedPresent)
fail("Expected to find $deserializeLambda$ in " + clazz);
}
}
static class Empty {}
public void testEmptyClass() {
assertDeserializeMethod(Empty.class, false);
}
static class Cap1 {
void foo() {
Runnable r = (Runnable & Serializable) () -> { };
}
}
public void testCapturingSerLambda() {
assertDeserializeMethod(Cap1.class, true);
}
static class Cap2 {
void foo() {
Runnable r = () -> { };
}
}
public void testCapturingNonSerLambda() {
assertDeserializeMethod(Cap2.class, false);
}
interface Marker { }
static class Cap3 {
void foo() {
Runnable r = (Runnable & Marker) () -> { };
}
}
public void testCapturingNonserIntersectionLambda() {
assertDeserializeMethod(Cap3.class, false);
}
}

View file

@ -0,0 +1,49 @@
/*
* Copyright (c) 2012, 2013, 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.
*/
package org.openjdk.tests.java.lang.invoke;
import org.testng.annotations.Test;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandleProxies;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import static org.testng.Assert.assertEquals;
/**
* MHProxiesTest -- regression test for MH library bug
*/
@Test
public class MHProxiesTest {
public interface Sam { double m(int arg); }
public static Byte m(int arg) { return (byte) arg; }
public void testProxy() throws NoSuchMethodException, IllegalAccessException {
MethodHandle m = MethodHandles.lookup().findStatic(MHProxiesTest.class, "m",
MethodType.methodType(Byte.class, int.class));
Sam s = MethodHandleProxies.asInterfaceInstance(Sam.class, m);
assertEquals(66d, s.m(66));
}
}

View file

@ -0,0 +1,357 @@
/*
* Copyright (c) 2012, 2013, 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.
*/
package org.openjdk.tests.java.lang.invoke;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.NotSerializableException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.lang.invoke.CallSite;
import java.lang.invoke.LambdaMetafactory;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicLong;
import java.util.function.BiPredicate;
import java.util.function.Consumer;
import java.util.function.LongConsumer;
import java.util.function.Predicate;
import java.util.function.Supplier;
import org.testng.annotations.Test;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertTrue;
import static org.testng.Assert.fail;
/**
* SerializedLambdaTest
*
* @author Brian Goetz
*/
@Test
public class SerializedLambdaTest {
public static final int REPS = 50;
@SuppressWarnings("unchecked")
private<T> void assertSerial(T p, Consumer<T> asserter) throws IOException, ClassNotFoundException {
asserter.accept(p);
for (int i=0; i<REPS; i++) {
byte[] bytes = serialize(p);
assertTrue(bytes.length > 0);
asserter.accept((T) deserialize(bytes));
}
}
private void assertNotSerial(Predicate<String> p, Consumer<Predicate<String>> asserter)
throws IOException, ClassNotFoundException {
asserter.accept(p);
try {
byte[] bytes = serialize(p);
fail("Expected serialization failure");
}
catch (NotSerializableException e) {
// success
}
}
private byte[] serialize(Object o) throws IOException {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(o);
oos.close();
return bos.toByteArray();
}
private Object deserialize(byte[] bytes) throws IOException, ClassNotFoundException {
try(ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bytes))) {
return ois.readObject();
}
}
// Test instantiating against intersection type
public void testSimpleSerializedInstantiation() throws IOException, ClassNotFoundException {
@SuppressWarnings("unchecked")
Predicate<String> pred = (Predicate<String> & Serializable) s -> true;
assertSerial(pred,
p -> {
assertTrue(p instanceof Predicate);
assertTrue(p instanceof Serializable);
assertTrue(p.test(""));
});
}
interface SerPredicate<T> extends Predicate<T>, Serializable { }
// Test instantiating against derived type
public void testSimpleSerializedInstantiation2() throws IOException, ClassNotFoundException {
SerPredicate<String> serPred = (SerPredicate<String>) s -> true;
assertSerial(serPred,
p -> {
assertTrue(p instanceof Predicate);
assertTrue(p instanceof Serializable);
assertTrue(p instanceof SerPredicate);
assertTrue(p.test(""));
});
}
// Negative test: non-serializable lambdas are in fact not serializable
public void testNonserializableInstantiation() throws IOException, ClassNotFoundException {
@SuppressWarnings("unchecked")
Predicate<String> pred = (Predicate<String>) s -> true;
assertNotSerial(pred,
p -> {
assertTrue(p instanceof Predicate);
assertFalse(p instanceof Serializable);
assertTrue(p.test(""));
});
}
// Test lambda capturing int
public void testSerializeCapturingInt() throws IOException, ClassNotFoundException {
class Moo {
@SuppressWarnings("unchecked")
Predicate<String> foo(int x) {
return (Predicate<String> & Serializable) s -> s.length() >= x;
}
}
Predicate<String> pred = new Moo().foo(3);
assertSerial(pred, p -> {
assertTrue(p.test("yada"));
assertFalse(p.test("no"));
});
}
// Test lambda capturing String
public void testSerializeCapturingString() throws IOException, ClassNotFoundException {
class Moo {
@SuppressWarnings("unchecked")
Predicate<String> foo(String t) {
return (Predicate<String> & Serializable) s -> s.equals(t);
}
}
Predicate<String> pred = new Moo().foo("goo");
assertSerial(pred, p -> {
assertTrue(p.test("goo"));
assertFalse(p.test("foo"));
});
}
// Negative test: lambdas that capture a non-serializable var
public void testSerializeCapturingNonSerializable() throws IOException, ClassNotFoundException {
class Box {
String s;
Box(String s) { this.s = s; }
}
class Moo {
@SuppressWarnings("unchecked")
Predicate<String> foo(Box b) {
return (Predicate<String> & Serializable) s -> s.equals(b.s);
}
}
Predicate<String> pred = new Moo().foo(new Box("goo"));
assertNotSerial(pred, p -> {
assertTrue(p.test("goo"));
assertFalse(p.test("foo"));
});
}
static boolean startsWithA(String s) {
return s.startsWith("a");
}
// Test static method ref
public void testStaticMR() throws IOException, ClassNotFoundException {
@SuppressWarnings("unchecked")
Predicate<String> mh1 = (Predicate<String> & Serializable) SerializedLambdaTest::startsWithA;
@SuppressWarnings("unchecked")
Predicate<String> mh2 = (SerPredicate<String>) SerializedLambdaTest::startsWithA;
Consumer<Predicate<String>> b = p -> {
assertTrue(p instanceof Serializable);
assertTrue(p.test("arf"));
assertFalse(p.test("barf"));
};
assertSerial(mh1, b);
assertSerial(mh2, b);
}
// Test unbound method ref of nonserializable class -- should still succeed
public void testUnboundMR() throws IOException, ClassNotFoundException {
class Moo {
public boolean startsWithB(String s) {
return s.startsWith("b");
}
}
@SuppressWarnings("unchecked")
BiPredicate<Moo, String> mh1 = (BiPredicate<Moo, String> & Serializable) Moo::startsWithB;
Consumer<BiPredicate<Moo, String>> b = p -> {
assertTrue(p instanceof Serializable);
assertTrue(p.test(new Moo(), "barf"));
assertFalse(p.test(new Moo(), "arf"));
};
assertSerial(mh1, b);
}
// Negative test: test bound MR of nonserializable class
public void testBoundMRNotSerReceiver() throws IOException, ClassNotFoundException {
class Moo {
public boolean startsWithB(String s) {
return s.startsWith("b");
}
}
Moo moo = new Moo();
@SuppressWarnings("unchecked")
Predicate<String> mh1 = (Predicate<String> & Serializable) moo::startsWithB;
@SuppressWarnings("unchecked")
Predicate<String> mh2 = (SerPredicate<String>) moo::startsWithB;
Consumer<Predicate<String>> b = p -> {
assertTrue(p instanceof Serializable);
assertTrue(p.test("barf"));
assertFalse(p.test("arf"));
};
assertNotSerial(mh1, b);
assertNotSerial(mh2, b);
}
// Test bound MR of serializable class
@SuppressWarnings("serial")
static class ForBoundMRef implements Serializable {
public boolean startsWithB(String s) {
return s.startsWith("b");
}
}
public void testBoundMR() throws IOException, ClassNotFoundException {
ForBoundMRef moo = new ForBoundMRef();
@SuppressWarnings("unchecked")
Predicate<String> mh1 = (Predicate<String> & Serializable) moo::startsWithB;
@SuppressWarnings("unchecked")
Predicate<String> mh2 = (SerPredicate<String>) moo::startsWithB;
Consumer<Predicate<String>> b = p -> {
assertTrue(p instanceof Serializable);
assertTrue(p.test("barf"));
assertFalse(p.test("arf"));
};
assertSerial(mh1, b);
assertSerial(mh2, b);
}
static class ForCtorRef {
public boolean startsWithB(String s) {
return s.startsWith("b");
}
}
// Test ctor ref of nonserializable class
public void testCtorRef() throws IOException, ClassNotFoundException {
@SuppressWarnings("unchecked")
Supplier<ForCtorRef> ctor = (Supplier<ForCtorRef> & Serializable) ForCtorRef::new;
Consumer<Supplier<ForCtorRef>> b = s -> {
assertTrue(s instanceof Serializable);
ForCtorRef m = s.get();
assertTrue(m.startsWithB("barf"));
assertFalse(m.startsWithB("arf"));
};
assertSerial(ctor, b);
}
//Test throwing away return type
public void testDiscardReturnBound() throws IOException, ClassNotFoundException {
List<String> list = new ArrayList<>();
Consumer<String> c = (Consumer<String> & Serializable) list::add;
assertSerial(c, cc -> { assertTrue(cc instanceof Consumer); });
AtomicLong a = new AtomicLong();
LongConsumer lc = (LongConsumer & Serializable) a::addAndGet;
assertSerial(lc, plc -> { plc.accept(3); });
}
// Tests of direct use of metafactories
private static boolean foo(Object s) { return s != null && ((String) s).length() > 0; }
private static final MethodType predicateMT = MethodType.methodType(boolean.class, Object.class);
private static final MethodType stringPredicateMT = MethodType.methodType(boolean.class, String.class);
private static final Consumer<Predicate<String>> fooAsserter = x -> {
assertTrue(x.test("foo"));
assertFalse(x.test(""));
assertFalse(x.test(null));
};
// standard MF: nonserializable supertype
public void testDirectStdNonser() throws Throwable {
MethodHandle fooMH = MethodHandles.lookup().findStatic(SerializedLambdaTest.class, "foo", predicateMT);
// Standard metafactory, non-serializable target: not serializable
CallSite cs = LambdaMetafactory.metafactory(MethodHandles.lookup(),
"test", MethodType.methodType(Predicate.class),
predicateMT, fooMH, stringPredicateMT);
Predicate<String> p = (Predicate<String>) cs.getTarget().invokeExact();
assertNotSerial(p, fooAsserter);
}
// standard MF: serializable supertype
public void testDirectStdSer() throws Throwable {
MethodHandle fooMH = MethodHandles.lookup().findStatic(SerializedLambdaTest.class, "foo", predicateMT);
// Standard metafactory, serializable target: not serializable
CallSite cs = LambdaMetafactory.metafactory(MethodHandles.lookup(),
"test", MethodType.methodType(SerPredicate.class),
predicateMT, fooMH, stringPredicateMT);
assertNotSerial((SerPredicate<String>) cs.getTarget().invokeExact(), fooAsserter);
}
// alt MF: nonserializable supertype
public void testAltStdNonser() throws Throwable {
MethodHandle fooMH = MethodHandles.lookup().findStatic(SerializedLambdaTest.class, "foo", predicateMT);
// Alt metafactory, non-serializable target: not serializable
CallSite cs = LambdaMetafactory.altMetafactory(MethodHandles.lookup(),
"test", MethodType.methodType(Predicate.class),
predicateMT, fooMH, stringPredicateMT, 0);
assertNotSerial((Predicate<String>) cs.getTarget().invokeExact(), fooAsserter);
}
// alt MF: serializable supertype
public void testAltStdSer() throws Throwable {
MethodHandle fooMH = MethodHandles.lookup().findStatic(SerializedLambdaTest.class, "foo", predicateMT);
// Alt metafactory, serializable target, no FLAG_SERIALIZABLE: not serializable
CallSite cs = LambdaMetafactory.altMetafactory(MethodHandles.lookup(),
"test", MethodType.methodType(SerPredicate.class),
predicateMT, fooMH, stringPredicateMT, 0);
assertNotSerial((SerPredicate<String>) cs.getTarget().invokeExact(), fooAsserter);
// Alt metafactory, serializable marker, no FLAG_SERIALIZABLE: not serializable
cs = LambdaMetafactory.altMetafactory(MethodHandles.lookup(),
"test", MethodType.methodType(Predicate.class),
predicateMT, fooMH, stringPredicateMT, LambdaMetafactory.FLAG_MARKERS, 1, Serializable.class);
assertNotSerial((Predicate<String>) cs.getTarget().invokeExact(), fooAsserter);
}
}

View file

@ -0,0 +1,56 @@
/*
* Copyright (c) 2012, 2013, 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.
*/
package org.openjdk.tests.java.util;
import java.util.Arrays;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.testng.annotations.Test;
import static org.testng.Assert.*;
@Test(groups = "lib")
public class FillableStringTest {
public Stream<String> generate() {
return Arrays.asList("one", "two", "three", "four", "five", "six").stream()
.filter(s->s.length() > 3)
.map(String::toUpperCase);
}
public void testStringBuilder() {
String s = generate().collect(Collectors.joining());
assertEquals(s, "THREEFOURFIVE");
}
public void testStringBuffer() {
String s = generate().collect(Collectors.joining());
assertEquals(s, "THREEFOURFIVE");
}
public void testStringJoiner() {
String s = generate().collect(Collectors.joining("-"));
assertEquals(s, "THREE-FOUR-FIVE");
}
}

View file

@ -0,0 +1,93 @@
/*
* Copyright (c) 2012, 2013, 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.
*/
package org.openjdk.tests.java.util;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.stream.LambdaTestHelpers;
import org.testng.annotations.AfterClass;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import static org.testng.Assert.assertEquals;
/**
* Unit tests for extension methods on Map
*/
public class MapTest {
private static final Map<Integer, String> EXPECTED = new HashMap<>();
private Map<Integer, String> map;
@BeforeClass
public void setUpClass() {
EXPECTED.put(0, "zero");
EXPECTED.put(1, "one");
EXPECTED.put(2, "two");
EXPECTED.put(3, "three");
EXPECTED.put(4, "four");
EXPECTED.put(5, "five");
EXPECTED.put(6, "six");
EXPECTED.put(7, "seven");
EXPECTED.put(8, "eight");
EXPECTED.put(9, "nine");
}
@AfterClass
public void tearDownClass() {
EXPECTED.clear();
}
@BeforeMethod
public void setUp() {
map = new HashMap<>(EXPECTED);
}
@AfterMethod
public void tearDown() {
map.clear();
map = null;
}
@Test(groups = { "serialization-hostile" })
public void testForEach() {
final Set<String> values = new HashSet<>(EXPECTED.size());
map.forEach((k, v) -> {values.add(v);});
LambdaTestHelpers.assertContentsUnordered(values, EXPECTED.values());
}
@Test
public void testReplaceAll() {
map.replaceAll((k, v) -> {return v.toUpperCase();});
for (final Map.Entry<Integer, String> entry : map.entrySet()) {
assertEquals(entry.getValue(), EXPECTED.get(entry.getKey()).toUpperCase());
}
}
}

View file

@ -0,0 +1,367 @@
/*
* 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
* 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.
*/
package org.openjdk.tests.java.util;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.Spliterator;
import java.util.SplittableRandom;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.DoubleStream;
import java.util.stream.DoubleStreamTestScenario;
import java.util.stream.IntStream;
import java.util.stream.IntStreamTestScenario;
import java.util.stream.LongStream;
import java.util.stream.LongStreamTestScenario;
import java.util.stream.OpTestCase;
import java.util.stream.StreamSupport;
import java.util.stream.TestData;
@Test
public class SplittableRandomTest extends OpTestCase {
static class RandomBoxedSpliterator<T> implements Spliterator<T> {
final SplittableRandom rng;
long index;
final long fence;
final Function<SplittableRandom, T> rngF;
RandomBoxedSpliterator(SplittableRandom rng, long index, long fence, Function<SplittableRandom, T> rngF) {
this.rng = rng;
this.index = index;
this.fence = fence;
this.rngF = rngF;
}
public RandomBoxedSpliterator<T> trySplit() {
long i = index, m = (i + fence) >>> 1;
return (m <= i) ? null :
new RandomBoxedSpliterator<>(rng.split(), i, index = m, rngF);
}
public long estimateSize() {
return fence - index;
}
public int characteristics() {
return (Spliterator.SIZED | Spliterator.SUBSIZED |
Spliterator.NONNULL | Spliterator.IMMUTABLE);
}
@Override
public boolean tryAdvance(Consumer<? super T> consumer) {
if (consumer == null) throw new NullPointerException();
long i = index, f = fence;
if (i < f) {
consumer.accept(rngF.apply(rng));
index = i + 1;
return true;
}
return false;
}
}
static final int SIZE = 1 << 16;
// Ensure there is a range of a power of 2
static final int[] BOUNDS = {256};
static final int[] ORIGINS = {-16, 0, 16};
static <T extends Comparable<T>> ResultAsserter<Iterable<T>> randomAsserter(int size, T origin, T bound) {
return (act, exp, ord, par) -> {
int count = 0;
Set<Comparable<T>> values = new HashSet<>();
for (Comparable<T> t : act) {
if (origin.compareTo(bound) < 0) {
assertTrue(t.compareTo(origin) >= 0);
assertTrue(t.compareTo(bound) < 0);
}
values.add(t);
count++;
}
assertEquals(count, size);
// Assert that at least one different result is produced
// For the size of the data it is highly improbable that this
// will cause a false negative (i.e. a false failure)
assertTrue(values.size() > 1);
};
}
@DataProvider(name = "ints")
public static Object[][] intsDataProvider() {
List<Object[]> data = new ArrayList<>();
// Function to create a stream using a RandomBoxedSpliterator
Function<Function<SplittableRandom, Integer>, IntStream> rbsf =
sf -> StreamSupport.stream(new RandomBoxedSpliterator<>(new SplittableRandom(), 0, SIZE, sf), false).
mapToInt(i -> i);
// Unbounded
data.add(new Object[]{
TestData.Factory.ofIntSupplier(
String.format("new SplittableRandom().ints().limit(%d)", SIZE),
() -> new SplittableRandom().ints().limit(SIZE)),
randomAsserter(SIZE, Integer.MAX_VALUE, 0)
});
data.add(new Object[]{
TestData.Factory.ofIntSupplier(
String.format("new SplittableRandom().ints(%d)", SIZE),
() -> new SplittableRandom().ints(SIZE)),
randomAsserter(SIZE, Integer.MAX_VALUE, 0)
});
data.add(new Object[]{
TestData.Factory.ofIntSupplier(
String.format("new RandomBoxedSpliterator(0, %d, sr -> sr.nextInt())", SIZE),
() -> rbsf.apply(sr -> sr.nextInt())),
randomAsserter(SIZE, Integer.MAX_VALUE, 0)
});
// Bounded
for (int b : BOUNDS) {
for (int o : ORIGINS) {
final int origin = o;
final int bound = b;
data.add(new Object[]{
TestData.Factory.ofIntSupplier(
String.format("new SplittableRandom().ints(%d, %d).limit(%d)", origin, bound, SIZE),
() -> new SplittableRandom().ints(origin, bound).limit(SIZE)),
randomAsserter(SIZE, origin, bound)
});
data.add(new Object[]{
TestData.Factory.ofIntSupplier(
String.format("new SplittableRandom().ints(%d, %d, %d)", SIZE, origin, bound),
() -> new SplittableRandom().ints(SIZE, origin, bound)),
randomAsserter(SIZE, origin, bound)
});
if (origin == 0) {
data.add(new Object[]{
TestData.Factory.ofIntSupplier(
String.format("new RandomBoxedSpliterator(0, %d, sr -> sr.nextInt(%d))", SIZE, bound),
() -> rbsf.apply(sr -> sr.nextInt(bound))),
randomAsserter(SIZE, origin, bound)
});
}
data.add(new Object[]{
TestData.Factory.ofIntSupplier(
String.format("new RandomBoxedSpliterator(0, %d, sr -> sr.nextInt(%d, %d))", SIZE, origin, bound),
() -> rbsf.apply(sr -> sr.nextInt(origin, bound))),
randomAsserter(SIZE, origin, bound)
});
}
}
return data.toArray(new Object[0][]);
}
@Test(dataProvider = "ints")
public void testInts(TestData.OfInt data, ResultAsserter<Iterable<Integer>> ra) {
withData(data).
stream(s -> s).
without(IntStreamTestScenario.CLEAR_SIZED_SCENARIOS).
resultAsserter(ra).
exercise();
}
@DataProvider(name = "longs")
public static Object[][] longsDataProvider() {
List<Object[]> data = new ArrayList<>();
// Function to create a stream using a RandomBoxedSpliterator
Function<Function<SplittableRandom, Long>, LongStream> rbsf =
sf -> StreamSupport.stream(new RandomBoxedSpliterator<>(new SplittableRandom(), 0, SIZE, sf), false).
mapToLong(i -> i);
// Unbounded
data.add(new Object[]{
TestData.Factory.ofLongSupplier(
String.format("new SplittableRandom().longs().limit(%d)", SIZE),
() -> new SplittableRandom().longs().limit(SIZE)),
randomAsserter(SIZE, Long.MAX_VALUE, 0L)
});
data.add(new Object[]{
TestData.Factory.ofLongSupplier(
String.format("new SplittableRandom().longs(%d)", SIZE),
() -> new SplittableRandom().longs(SIZE)),
randomAsserter(SIZE, Long.MAX_VALUE, 0L)
});
data.add(new Object[]{
TestData.Factory.ofLongSupplier(
String.format("new RandomBoxedSpliterator(0, %d, sr -> sr.nextLong())", SIZE),
() -> rbsf.apply(sr -> sr.nextLong())),
randomAsserter(SIZE, Long.MAX_VALUE, 0L)
});
// Bounded
for (int b : BOUNDS) {
for (int o : ORIGINS) {
final long origin = o;
final long bound = b;
data.add(new Object[]{
TestData.Factory.ofLongSupplier(
String.format("new SplittableRandom().longs(%d, %d).limit(%d)", origin, bound, SIZE),
() -> new SplittableRandom().longs(origin, bound).limit(SIZE)),
randomAsserter(SIZE, origin, bound)
});
data.add(new Object[]{
TestData.Factory.ofLongSupplier(
String.format("new SplittableRandom().longs(%d, %d, %d)", SIZE, origin, bound),
() -> new SplittableRandom().longs(SIZE, origin, bound)),
randomAsserter(SIZE, origin, bound)
});
if (origin == 0) {
data.add(new Object[]{
TestData.Factory.ofLongSupplier(
String.format("new RandomBoxedSpliterator(0, %d, sr -> sr.nextLong(%d))", SIZE, bound),
() -> rbsf.apply(sr -> sr.nextLong(bound))),
randomAsserter(SIZE, origin, bound)
});
}
data.add(new Object[]{
TestData.Factory.ofLongSupplier(
String.format("new RandomBoxedSpliterator(0, %d, sr -> sr.nextLong(%d, %d))", SIZE, origin, bound),
() -> rbsf.apply(sr -> sr.nextLong(origin, bound))),
randomAsserter(SIZE, origin, bound)
});
}
}
return data.toArray(new Object[0][]);
}
@Test(dataProvider = "longs")
public void testLongs(TestData.OfLong data, ResultAsserter<Iterable<Long>> ra) {
withData(data).
stream(s -> s).
without(LongStreamTestScenario.CLEAR_SIZED_SCENARIOS).
resultAsserter(ra).
exercise();
}
@DataProvider(name = "doubles")
public static Object[][] doublesDataProvider() {
List<Object[]> data = new ArrayList<>();
// Function to create a stream using a RandomBoxedSpliterator
Function<Function<SplittableRandom, Double>, DoubleStream> rbsf =
sf -> StreamSupport.stream(new RandomBoxedSpliterator<>(new SplittableRandom(), 0, SIZE, sf), false).
mapToDouble(i -> i);
// Unbounded
data.add(new Object[]{
TestData.Factory.ofDoubleSupplier(
String.format("new SplittableRandom().doubles().limit(%d)", SIZE),
() -> new SplittableRandom().doubles().limit(SIZE)),
randomAsserter(SIZE, Double.MAX_VALUE, 0d)
});
data.add(new Object[]{
TestData.Factory.ofDoubleSupplier(
String.format("new SplittableRandom().doubles(%d)", SIZE),
() -> new SplittableRandom().doubles(SIZE)),
randomAsserter(SIZE, Double.MAX_VALUE, 0d)
});
data.add(new Object[]{
TestData.Factory.ofDoubleSupplier(
String.format("new RandomBoxedSpliterator(0, %d, sr -> sr.nextDouble())", SIZE),
() -> rbsf.apply(sr -> sr.nextDouble())),
randomAsserter(SIZE, Double.MAX_VALUE, 0d)
});
// Bounded
for (int b : BOUNDS) {
for (int o : ORIGINS) {
final double origin = o;
final double bound = b;
data.add(new Object[]{
TestData.Factory.ofDoubleSupplier(
String.format("new SplittableRandom().doubles(%f, %f).limit(%d)", origin, bound, SIZE),
() -> new SplittableRandom().doubles(origin, bound).limit(SIZE)),
randomAsserter(SIZE, origin, bound)
});
data.add(new Object[]{
TestData.Factory.ofDoubleSupplier(
String.format("new SplittableRandom().doubles(%d, %f, %f)", SIZE, origin, bound),
() -> new SplittableRandom().doubles(SIZE, origin, bound)),
randomAsserter(SIZE, origin, bound)
});
if (origin == 0) {
data.add(new Object[]{
TestData.Factory.ofDoubleSupplier(
String.format("new RandomBoxedSpliterator(0, %d, sr -> sr.nextDouble(%f))", SIZE, bound),
() -> rbsf.apply(sr -> sr.nextDouble(bound))),
randomAsserter(SIZE, origin, bound)
});
}
data.add(new Object[]{
TestData.Factory.ofDoubleSupplier(
String.format("new RandomBoxedSpliterator(0, %d, sr -> sr.nextDouble(%f, %f))", SIZE, origin, bound),
() -> rbsf.apply(sr -> sr.nextDouble(origin, bound))),
randomAsserter(SIZE, origin, bound)
});
}
}
return data.toArray(new Object[0][]);
}
@Test(dataProvider = "doubles")
public void testDoubles(TestData.OfDouble data, ResultAsserter<Iterable<Double>> ra) {
withData(data).
stream(s -> s).
without(DoubleStreamTestScenario.CLEAR_SIZED_SCENARIOS).
resultAsserter(ra).
exercise();
}
}

View file

@ -0,0 +1,196 @@
/*
* Copyright (c) 2012, 2017, 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
* @summary primtive stream collection with summary statistics
* @bug 8044047 8178117
*/
package org.openjdk.tests.java.util.stream;
import org.testng.annotations.Test;
import java.util.ArrayList;
import java.util.DoubleSummaryStatistics;
import java.util.IntSummaryStatistics;
import java.util.List;
import java.util.LongSummaryStatistics;
import java.util.stream.Collectors;
import java.util.stream.DoubleStream;
import java.util.stream.IntStream;
import java.util.stream.LongStream;
import java.util.stream.OpTestCase;
import static java.util.stream.LambdaTestHelpers.countTo;
import static java.util.stream.ThrowableHelper.checkNPE;
@Test
public class CollectAndSummaryStatisticsTest extends OpTestCase {
public void testIntCollectNull() {
checkNPE(() -> IntStream.of(1).collect(null,
IntSummaryStatistics::accept,
IntSummaryStatistics::combine));
checkNPE(() -> IntStream.of(1).collect(IntSummaryStatistics::new,
null,
IntSummaryStatistics::combine));
checkNPE(() -> IntStream.of(1).collect(IntSummaryStatistics::new,
IntSummaryStatistics::accept,
null));
}
public void testLongCollectNull() {
checkNPE(() -> LongStream.of(1).collect(null,
LongSummaryStatistics::accept,
LongSummaryStatistics::combine));
checkNPE(() -> LongStream.of(1).collect(LongSummaryStatistics::new,
null,
LongSummaryStatistics::combine));
checkNPE(() -> LongStream.of(1).collect(LongSummaryStatistics::new,
LongSummaryStatistics::accept,
null));
}
public void testDoubleCollectNull() {
checkNPE(() -> DoubleStream.of(1).collect(null,
DoubleSummaryStatistics::accept,
DoubleSummaryStatistics::combine));
checkNPE(() -> DoubleStream.of(1).collect(DoubleSummaryStatistics::new,
null,
DoubleSummaryStatistics::combine));
checkNPE(() -> DoubleStream.of(1).collect(DoubleSummaryStatistics::new,
DoubleSummaryStatistics::accept,
null));
}
public void testIntStatistics() {
List<IntSummaryStatistics> instances = new ArrayList<>();
instances.add(countTo(1000).stream().collect(Collectors.summarizingInt(i -> i)));
instances.add(countTo(1000).stream().mapToInt(i -> i).summaryStatistics());
instances.add(countTo(1000).stream().mapToInt(i -> i).collect(IntSummaryStatistics::new,
IntSummaryStatistics::accept,
IntSummaryStatistics::combine));
instances.add(countTo(1000).stream().mapToInt(i -> i).collect(() -> new IntSummaryStatistics(0, -1, 1001, 2),
IntSummaryStatistics::accept,
IntSummaryStatistics::combine));
instances.add(countTo(1000).parallelStream().collect(Collectors.summarizingInt(i -> i)));
instances.add(countTo(1000).parallelStream().mapToInt(i -> i).summaryStatistics());
instances.add(countTo(1000).parallelStream().mapToInt(i -> i).collect(IntSummaryStatistics::new,
IntSummaryStatistics::accept,
IntSummaryStatistics::combine));
instances.add(countTo(1000).parallelStream().mapToInt(i -> i).collect(() -> new IntSummaryStatistics(0, -1, 1001, 2),
IntSummaryStatistics::accept,
IntSummaryStatistics::combine));
IntSummaryStatistics original = instances.get(0);
instances.add(new IntSummaryStatistics(original.getCount(), original.getMin(), original.getMax(), original.getSum()));
for (IntSummaryStatistics stats : instances) {
assertEquals(stats.getCount(), 1000);
assertEquals(stats.getSum(), countTo(1000).stream().mapToInt(i -> i).sum());
assertEquals(stats.getAverage(), (double) stats.getSum() / stats.getCount());
assertEquals(stats.getMax(), 1000);
assertEquals(stats.getMin(), 1);
}
expectThrows(IllegalArgumentException.class, () -> new IntSummaryStatistics(-1, 0, 0, 0));
expectThrows(IllegalArgumentException.class, () -> new IntSummaryStatistics(1, 3, 2, 0));
}
public void testLongStatistics() {
List<LongSummaryStatistics> instances = new ArrayList<>();
instances.add(countTo(1000).stream().collect(Collectors.summarizingLong(i -> i)));
instances.add(countTo(1000).stream().mapToLong(i -> i).summaryStatistics());
instances.add(countTo(1000).stream().mapToLong(i -> i).collect(LongSummaryStatistics::new,
LongSummaryStatistics::accept,
LongSummaryStatistics::combine));
instances.add(countTo(1000).stream().mapToInt(i -> i).collect(() -> new LongSummaryStatistics(0, -1, 1001, 2),
LongSummaryStatistics::accept,
LongSummaryStatistics::combine));
instances.add(countTo(1000).parallelStream().collect(Collectors.summarizingLong(i -> i)));
instances.add(countTo(1000).parallelStream().mapToLong(i -> i).summaryStatistics());
instances.add(countTo(1000).parallelStream().mapToLong(i -> i).collect(LongSummaryStatistics::new,
LongSummaryStatistics::accept,
LongSummaryStatistics::combine));
instances.add(countTo(1000).parallelStream().mapToInt(i -> i).collect(() -> new LongSummaryStatistics(0, -1, 1001, 2),
LongSummaryStatistics::accept,
LongSummaryStatistics::combine));
LongSummaryStatistics original = instances.get(0);
instances.add(new LongSummaryStatistics(original.getCount(), original.getMin(), original.getMax(), original.getSum()));
for (LongSummaryStatistics stats : instances) {
assertEquals(stats.getCount(), 1000);
assertEquals(stats.getSum(), (long) countTo(1000).stream().mapToInt(i -> i).sum());
assertEquals(stats.getAverage(), (double) stats.getSum() / stats.getCount());
assertEquals(stats.getMax(), 1000L);
assertEquals(stats.getMin(), 1L);
}
expectThrows(IllegalArgumentException.class, () -> new LongSummaryStatistics(-1, 0, 0, 0));
expectThrows(IllegalArgumentException.class, () -> new LongSummaryStatistics(1, 3, 2, 0));
}
public void testDoubleStatistics() {
List<DoubleSummaryStatistics> instances = new ArrayList<>();
instances.add(countTo(1000).stream().collect(Collectors.summarizingDouble(i -> i)));
instances.add(countTo(1000).stream().mapToDouble(i -> i).summaryStatistics());
instances.add(countTo(1000).stream().mapToDouble(i -> i).collect(DoubleSummaryStatistics::new,
DoubleSummaryStatistics::accept,
DoubleSummaryStatistics::combine));
instances.add(countTo(1000).stream().mapToInt(i -> i).collect(() -> new DoubleSummaryStatistics(0, -1, 1001, 2),
DoubleSummaryStatistics::accept,
DoubleSummaryStatistics::combine));
instances.add(countTo(1000).parallelStream().collect(Collectors.summarizingDouble(i -> i)));
instances.add(countTo(1000).parallelStream().mapToDouble(i -> i).summaryStatistics());
instances.add(countTo(1000).parallelStream().mapToDouble(i -> i).collect(DoubleSummaryStatistics::new,
DoubleSummaryStatistics::accept,
DoubleSummaryStatistics::combine));
instances.add(countTo(1000).parallelStream().mapToInt(i -> i).collect(() -> new DoubleSummaryStatistics(0, -1, 1001, 2),
DoubleSummaryStatistics::accept,
DoubleSummaryStatistics::combine));
DoubleSummaryStatistics original = instances.get(0);
instances.add(new DoubleSummaryStatistics(original.getCount(), original.getMin(), original.getMax(), original.getSum()));
for (DoubleSummaryStatistics stats : instances) {
assertEquals(stats.getCount(), 1000);
assertEquals(stats.getSum(), (double) countTo(1000).stream().mapToInt(i -> i).sum());
assertEquals(stats.getAverage(), stats.getSum() / stats.getCount());
assertEquals(stats.getMax(), 1000.0);
assertEquals(stats.getMin(), 1.0);
}
expectThrows(IllegalArgumentException.class, () -> new DoubleSummaryStatistics(-1, 0, 0, 0));
expectThrows(IllegalArgumentException.class, () -> new DoubleSummaryStatistics(1, 3, 2, 0));
double[] values = {1.0, Double.NaN};
for (var min : values) {
for (var max : values) {
for (var sum : values) {
if (Double.isNaN(min) && Double.isNaN(max) && Double.isNaN(sum)) continue;
if (!Double.isNaN(min) && !Double.isNaN(max) && !Double.isNaN(sum)) continue;
expectThrows(IllegalArgumentException.class, () -> new DoubleSummaryStatistics(1, min, max, sum));
}
}
}
}
}

View file

@ -0,0 +1,167 @@
/*
* 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
* 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.
*/
package org.openjdk.tests.java.util.stream;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedDeque;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ConcurrentSkipListMap;
import java.util.concurrent.ConcurrentSkipListSet;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.LinkedTransferQueue;
import java.util.concurrent.PriorityBlockingQueue;
import java.util.function.Supplier;
import java.util.stream.LambdaTestHelpers;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import java.util.*;
import java.util.stream.Stream;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
/**
* Tests laziness of stream operations -- mutations to the source after the stream() but prior to terminal operations
* are reflected in the stream contents.
*/
@Test
public class CollectionAndMapModifyStreamTest {
@DataProvider(name = "collections")
public Object[][] createCollections() {
List<Integer> content = LambdaTestHelpers.countTo(10);
List<Collection<Integer>> collections = new ArrayList<>();
collections.add(new ArrayList<>(content));
collections.add(new LinkedList<>(content));
collections.add(new Vector<>(content));
collections.add(new HashSet<>(content));
collections.add(new LinkedHashSet<>(content));
collections.add(new TreeSet<>(content));
Stack<Integer> stack = new Stack<>();
stack.addAll(content);
collections.add(stack);
collections.add(new PriorityQueue<>(content));
collections.add(new ArrayDeque<>(content));
// Concurrent collections
collections.add(new ConcurrentSkipListSet<>(content));
ArrayBlockingQueue<Integer> arrayBlockingQueue = new ArrayBlockingQueue<>(content.size());
for (Integer i : content)
arrayBlockingQueue.add(i);
collections.add(arrayBlockingQueue);
collections.add(new PriorityBlockingQueue<>(content));
collections.add(new LinkedBlockingQueue<>(content));
collections.add(new LinkedTransferQueue<>(content));
collections.add(new ConcurrentLinkedQueue<>(content));
collections.add(new LinkedBlockingDeque<>(content));
collections.add(new ConcurrentLinkedDeque<>(content));
Object[][] params = new Object[collections.size()][];
for (int i = 0; i < collections.size(); i++) {
params[i] = new Object[]{collections.get(i).getClass().getName(), collections.get(i)};
}
return params;
}
@Test(dataProvider = "collections")
public void testCollectionSizeRemove(String name, Collection<Integer> c) {
assertTrue(c.remove(1));
Stream<Integer> s = c.stream();
assertTrue(c.remove(2));
Object[] result = s.toArray();
assertEquals(result.length, c.size());
}
@DataProvider(name = "maps")
public Object[][] createMaps() {
Map<Integer, Integer> content = new HashMap<>();
for (int i = 0; i < 10; i++) {
content.put(i, i);
}
Map<String, Supplier<Map<Integer, Integer>>> maps = new HashMap<>();
maps.put(HashMap.class.getName(), () -> new HashMap<>(content));
maps.put(LinkedHashMap.class.getName(), () -> new LinkedHashMap<>(content));
maps.put(IdentityHashMap.class.getName(), () -> new IdentityHashMap<>(content));
maps.put(WeakHashMap.class.getName(), () -> new WeakHashMap<>(content));
maps.put(TreeMap.class.getName(), () -> new TreeMap<>(content));
maps.put(TreeMap.class.getName() + ".descendingMap()", () -> new TreeMap<>(content).descendingMap());
// The following are not lazy
// maps.put(TreeMap.class.getName() + ".descendingMap().descendingMap()", () -> new TreeMap<>(content).descendingMap().descendingMap());
// maps.put(TreeMap.class.getName() + ".headMap()", () -> new TreeMap<>(content).headMap(content.size() - 1));
// maps.put(TreeMap.class.getName() + ".descendingMap().headMap()", () -> new TreeMap<>(content).descendingMap().tailMap(content.size() - 1, false));
// Concurrent collections
maps.put(ConcurrentHashMap.class.getName(), () -> new ConcurrentHashMap<>(content));
maps.put(ConcurrentSkipListMap.class.getName(), () -> new ConcurrentSkipListMap<>(content));
Object[][] params = new Object[maps.size()][];
int i = 0;
for (Map.Entry<String, Supplier<Map<Integer, Integer>>> e : maps.entrySet()) {
params[i++] = new Object[]{e.getKey(), e.getValue()};
}
return params;
}
@Test(dataProvider = "maps", groups = { "serialization-hostile" })
public void testMapKeysSizeRemove(String name, Supplier<Map<Integer, Integer>> c) {
testCollectionSizeRemove(name + " key set", c.get().keySet());
}
@Test(dataProvider = "maps", groups = { "serialization-hostile" })
public void testMapValuesSizeRemove(String name, Supplier<Map<Integer, Integer>> c) {
testCollectionSizeRemove(name + " value set", c.get().values());
}
@Test(dataProvider = "maps")
public void testMapEntriesSizeRemove(String name, Supplier<Map<Integer, Integer>> c) {
testEntrySetSizeRemove(name + " entry set", c.get().entrySet());
}
private void testEntrySetSizeRemove(String name, Set<Map.Entry<Integer, Integer>> c) {
Map.Entry<Integer, Integer> first = c.iterator().next();
assertTrue(c.remove(first));
Stream<Map.Entry<Integer, Integer>> s = c.stream();
Map.Entry<Integer, Integer> second = c.iterator().next();
assertTrue(c.remove(second));
Object[] result = s.toArray();
assertEquals(result.length, c.size());
}
}

View file

@ -0,0 +1,105 @@
/*
* Copyright (c) 2019, 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.
*/
package org.openjdk.tests.java.util.stream;
/*
* THE CONTENTS OF THIS FILE HAVE TO BE IN SYNC WITH THE EXAMPLES USED
* IN THE JAVADOC.
*
* @test
* @bug 8231161
* @compile CollectorExample.java
* @summary Compilation test only. Compile code snippets from
* java.util.stream.Collector class-level API documentation
*/
import java.util.*;
import java.util.function.BiConsumer;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collector;
import java.util.stream.Collectors;
public class CollectorExample {
// Empty helper classes
class Widget {
}
class Employee {
public int getSalary() {
return 0; // money isn't everything
}
public Department getDepartment() {
return new Department();
}
}
class Department {
}
<T, A, R> void testSnippet1(Collector<T, A, R> collector, T t1, T t2) {
Supplier<A> supplier = collector.supplier();
BiConsumer<A, T> accumulator = collector.accumulator();
BinaryOperator<A> combiner = collector.combiner();
Function<A, R> finisher = collector.finisher();
// Example start
A a1 = supplier.get();
accumulator.accept(a1, t1);
accumulator.accept(a1, t2);
R r1 = finisher.apply(a1);
A a2 = supplier.get();
accumulator.accept(a2, t1);
A a3 = supplier.get();
accumulator.accept(a3, t2);
R r2 = finisher.apply(combiner.apply(a2, a3));
}
void testSnippet2() {
Collector<Widget, ?, TreeSet<Widget>> intoSet =
Collector.of(TreeSet::new, TreeSet::add,
(left, right) -> { left.addAll(right); return left; });
}
<T, A, R> void testSnippet3(Collector<T, A, R> collector, Collection<T> data) {
A container = collector.supplier().get();
for (T t : data)
collector.accumulator().accept(container, t);
collector.finisher().apply(container);
}
void testSnippet4and5() {
Collector<Employee, ?, Integer> summingSalaries
= Collectors.summingInt(Employee::getSalary);
Collector<Employee, ?, Map<Department, Integer>> summingSalariesByDept
= Collectors.groupingBy(Employee::getDepartment, summingSalaries);
}
}

View file

@ -0,0 +1,52 @@
/*
* Copyright (c) 2020, 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.
*/
package org.openjdk.tests.java.util.stream;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collector;
import java.util.stream.Collectors;
import org.testng.annotations.Test;
import static org.testng.Assert.*;
/*
* @test
* @bug 8254090
* @summary Test for Collectors.toUnmodifiableList().
*/
public class CollectorToUnmodListTest {
@SuppressWarnings("unchecked")
@Test
public void testFinisher() {
String[] array = { "x", "y", "z" };
List<String> in = new ArrayList<>() {
public Object[] toArray() {
return array;
}
};
var finisher = (Function<List<String>, List<String>>)Collectors.<String>toUnmodifiableList().finisher();
assertThrows(IllegalArgumentException.class, () -> finisher.apply(in));
}
}

View file

@ -0,0 +1,810 @@
/*
* Copyright (c) 2012, 2018, 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.
*/
package org.openjdk.tests.java.util.stream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.IntSummaryStatistics;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.StringJoiner;
import java.util.TreeMap;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentSkipListMap;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.BiFunction;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.stream.Collector;
import java.util.stream.Collectors;
import java.util.stream.LambdaTestHelpers;
import java.util.stream.OpTestCase;
import java.util.stream.Stream;
import java.util.stream.StreamOpFlagTestHelper;
import java.util.stream.StreamTestDataProvider;
import java.util.stream.TestData;
import org.testng.annotations.Test;
import static java.util.stream.Collectors.collectingAndThen;
import static java.util.stream.Collectors.flatMapping;
import static java.util.stream.Collectors.filtering;
import static java.util.stream.Collectors.groupingBy;
import static java.util.stream.Collectors.groupingByConcurrent;
import static java.util.stream.Collectors.mapping;
import static java.util.stream.Collectors.partitioningBy;
import static java.util.stream.Collectors.reducing;
import static java.util.stream.Collectors.toCollection;
import static java.util.stream.Collectors.toConcurrentMap;
import static java.util.stream.Collectors.toList;
import static java.util.stream.Collectors.toMap;
import static java.util.stream.Collectors.toSet;
import static java.util.stream.LambdaTestHelpers.assertContents;
import static java.util.stream.LambdaTestHelpers.assertContentsUnordered;
import static java.util.stream.LambdaTestHelpers.mDoubler;
/*
* @test
* @bug 8071600 8144675
* @summary Test for collectors.
*/
public class CollectorsTest extends OpTestCase {
private abstract static class CollectorAssertion<T, U> {
abstract void assertValue(U value,
Supplier<Stream<T>> source,
boolean ordered) throws ReflectiveOperationException;
}
static class MappingAssertion<T, V, R> extends CollectorAssertion<T, R> {
private final Function<T, V> mapper;
private final CollectorAssertion<V, R> downstream;
MappingAssertion(Function<T, V> mapper, CollectorAssertion<V, R> downstream) {
this.mapper = mapper;
this.downstream = downstream;
}
@Override
void assertValue(R value, Supplier<Stream<T>> source, boolean ordered) throws ReflectiveOperationException {
downstream.assertValue(value,
() -> source.get().map(mapper),
ordered);
}
}
static class FlatMappingAssertion<T, V, R> extends CollectorAssertion<T, R> {
private final Function<T, Stream<V>> mapper;
private final CollectorAssertion<V, R> downstream;
FlatMappingAssertion(Function<T, Stream<V>> mapper,
CollectorAssertion<V, R> downstream) {
this.mapper = mapper;
this.downstream = downstream;
}
@Override
void assertValue(R value, Supplier<Stream<T>> source, boolean ordered) throws ReflectiveOperationException {
downstream.assertValue(value,
() -> source.get().flatMap(mapper),
ordered);
}
}
static class FilteringAssertion<T, R> extends CollectorAssertion<T, R> {
private final Predicate<T> filter;
private final CollectorAssertion<T, R> downstream;
public FilteringAssertion(Predicate<T> filter, CollectorAssertion<T, R> downstream) {
this.filter = filter;
this.downstream = downstream;
}
@Override
void assertValue(R value, Supplier<Stream<T>> source, boolean ordered) throws ReflectiveOperationException {
downstream.assertValue(value,
() -> source.get().filter(filter),
ordered);
}
}
static class GroupingByAssertion<T, K, V, M extends Map<K, ? extends V>> extends CollectorAssertion<T, M> {
private final Class<? extends Map> clazz;
private final Function<T, K> classifier;
private final CollectorAssertion<T,V> downstream;
GroupingByAssertion(Function<T, K> classifier, Class<? extends Map> clazz,
CollectorAssertion<T, V> downstream) {
this.clazz = clazz;
this.classifier = classifier;
this.downstream = downstream;
}
@Override
void assertValue(M map,
Supplier<Stream<T>> source,
boolean ordered) throws ReflectiveOperationException {
if (!clazz.isAssignableFrom(map.getClass()))
fail(String.format("Class mismatch in GroupingByAssertion: %s, %s", clazz, map.getClass()));
assertContentsUnordered(map.keySet(), source.get().map(classifier).collect(toSet()));
for (Map.Entry<K, ? extends V> entry : map.entrySet()) {
K key = entry.getKey();
downstream.assertValue(entry.getValue(),
() -> source.get().filter(e -> classifier.apply(e).equals(key)),
ordered);
}
}
}
static class ToMapAssertion<T, K, V, M extends Map<K,V>> extends CollectorAssertion<T, M> {
private final Class<? extends Map> clazz;
private final Function<T, K> keyFn;
private final Function<T, V> valueFn;
private final BinaryOperator<V> mergeFn;
ToMapAssertion(Function<T, K> keyFn,
Function<T, V> valueFn,
BinaryOperator<V> mergeFn,
Class<? extends Map> clazz) {
this.clazz = clazz;
this.keyFn = keyFn;
this.valueFn = valueFn;
this.mergeFn = mergeFn;
}
@Override
void assertValue(M map, Supplier<Stream<T>> source, boolean ordered) throws ReflectiveOperationException {
if (!clazz.isAssignableFrom(map.getClass()))
fail(String.format("Class mismatch in ToMapAssertion: %s, %s", clazz, map.getClass()));
Set<K> uniqueKeys = source.get().map(keyFn).collect(toSet());
assertEquals(uniqueKeys, map.keySet());
source.get().forEach(t -> {
K key = keyFn.apply(t);
V v = source.get()
.filter(e -> key.equals(keyFn.apply(e)))
.map(valueFn)
.reduce(mergeFn)
.get();
assertEquals(map.get(key), v);
});
}
}
static class PartitioningByAssertion<T, D> extends CollectorAssertion<T, Map<Boolean,D>> {
private final Predicate<T> predicate;
private final CollectorAssertion<T,D> downstream;
PartitioningByAssertion(Predicate<T> predicate, CollectorAssertion<T, D> downstream) {
this.predicate = predicate;
this.downstream = downstream;
}
@Override
void assertValue(Map<Boolean, D> map,
Supplier<Stream<T>> source,
boolean ordered) throws ReflectiveOperationException {
if (!Map.class.isAssignableFrom(map.getClass()))
fail(String.format("Class mismatch in PartitioningByAssertion: %s", map.getClass()));
assertEquals(2, map.size());
downstream.assertValue(map.get(true), () -> source.get().filter(predicate), ordered);
downstream.assertValue(map.get(false), () -> source.get().filter(predicate.negate()), ordered);
}
}
static class ToListAssertion<T> extends CollectorAssertion<T, List<T>> {
@Override
void assertValue(List<T> value, Supplier<Stream<T>> source, boolean ordered)
throws ReflectiveOperationException {
if (!List.class.isAssignableFrom(value.getClass()))
fail(String.format("Class mismatch in ToListAssertion: %s", value.getClass()));
Stream<T> stream = source.get();
List<T> result = new ArrayList<>();
for (Iterator<T> it = stream.iterator(); it.hasNext(); ) // avoid capturing result::add
result.add(it.next());
if (StreamOpFlagTestHelper.isStreamOrdered(stream) && ordered)
assertContents(value, result);
else
assertContentsUnordered(value, result);
}
}
static class ToCollectionAssertion<T> extends CollectorAssertion<T, Collection<T>> {
private final Class<? extends Collection> clazz;
private final boolean targetOrdered;
ToCollectionAssertion(Class<? extends Collection> clazz, boolean targetOrdered) {
this.clazz = clazz;
this.targetOrdered = targetOrdered;
}
@Override
void assertValue(Collection<T> value, Supplier<Stream<T>> source, boolean ordered)
throws ReflectiveOperationException {
if (!clazz.isAssignableFrom(value.getClass()))
fail(String.format("Class mismatch in ToCollectionAssertion: %s, %s", clazz, value.getClass()));
Stream<T> stream = source.get();
Collection<T> result = clazz.newInstance();
for (Iterator<T> it = stream.iterator(); it.hasNext(); ) // avoid capturing result::add
result.add(it.next());
if (StreamOpFlagTestHelper.isStreamOrdered(stream) && targetOrdered && ordered)
assertContents(value, result);
else
assertContentsUnordered(value, result);
}
}
static class ReducingAssertion<T, U> extends CollectorAssertion<T, U> {
private final U identity;
private final Function<T, U> mapper;
private final BinaryOperator<U> reducer;
ReducingAssertion(U identity, Function<T, U> mapper, BinaryOperator<U> reducer) {
this.identity = identity;
this.mapper = mapper;
this.reducer = reducer;
}
@Override
void assertValue(U value, Supplier<Stream<T>> source, boolean ordered)
throws ReflectiveOperationException {
Optional<U> reduced = source.get().map(mapper).reduce(reducer);
if (value == null)
assertTrue(!reduced.isPresent());
else if (!reduced.isPresent()) {
assertEquals(value, identity);
}
else {
assertEquals(value, reduced.get());
}
}
}
static class TeeingAssertion<T, R1, R2, RR> extends CollectorAssertion<T, RR> {
private final Collector<T, ?, R1> c1;
private final Collector<T, ?, R2> c2;
private final BiFunction<? super R1, ? super R2, ? extends RR> finisher;
TeeingAssertion(Collector<T, ?, R1> c1, Collector<T, ?, R2> c2,
BiFunction<? super R1, ? super R2, ? extends RR> finisher) {
this.c1 = c1;
this.c2 = c2;
this.finisher = finisher;
}
@Override
void assertValue(RR value, Supplier<Stream<T>> source, boolean ordered) {
R1 r1 = source.get().collect(c1);
R2 r2 = source.get().collect(c2);
RR expected = finisher.apply(r1, r2);
assertEquals(value, expected);
}
}
private <T> ResultAsserter<T> mapTabulationAsserter(boolean ordered) {
return (act, exp, ord, par) -> {
if (par && (!ordered || !ord)) {
CollectorsTest.nestedMapEqualityAssertion(act, exp);
}
else {
LambdaTestHelpers.assertContentsEqual(act, exp);
}
};
}
private<T, M extends Map>
void exerciseMapCollection(TestData<T, Stream<T>> data,
Collector<T, ?, ? extends M> collector,
CollectorAssertion<T, M> assertion)
throws ReflectiveOperationException {
boolean ordered = !collector.characteristics().contains(Collector.Characteristics.UNORDERED);
M m = withData(data)
.terminal(s -> s.collect(collector))
.resultAsserter(mapTabulationAsserter(ordered))
.exercise();
assertion.assertValue(m, () -> data.stream(), ordered);
m = withData(data)
.terminal(s -> s.unordered().collect(collector))
.resultAsserter(mapTabulationAsserter(ordered))
.exercise();
assertion.assertValue(m, () -> data.stream(), false);
}
private static void nestedMapEqualityAssertion(Object o1, Object o2) {
if (o1 instanceof Map) {
Map m1 = (Map) o1;
Map m2 = (Map) o2;
assertContentsUnordered(m1.keySet(), m2.keySet());
for (Object k : m1.keySet())
nestedMapEqualityAssertion(m1.get(k), m2.get(k));
}
else if (o1 instanceof Collection) {
assertContentsUnordered(((Collection) o1), ((Collection) o2));
}
else
assertEquals(o1, o2);
}
private<T, R> void assertCollect(TestData.OfRef<T> data,
Collector<T, ?, R> collector,
Function<Stream<T>, R> streamReduction) {
R check = streamReduction.apply(data.stream());
withData(data).terminal(s -> s.collect(collector)).expectedResult(check).exercise();
}
@Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
public void testReducing(String name, TestData.OfRef<Integer> data) throws ReflectiveOperationException {
assertCollect(data, Collectors.reducing(0, Integer::sum),
s -> s.reduce(0, Integer::sum));
assertCollect(data, Collectors.reducing(Integer.MAX_VALUE, Integer::min),
s -> s.min(Integer::compare).orElse(Integer.MAX_VALUE));
assertCollect(data, Collectors.reducing(Integer.MIN_VALUE, Integer::max),
s -> s.max(Integer::compare).orElse(Integer.MIN_VALUE));
assertCollect(data, Collectors.reducing(Integer::sum),
s -> s.reduce(Integer::sum));
assertCollect(data, Collectors.minBy(Comparator.naturalOrder()),
s -> s.min(Integer::compare));
assertCollect(data, Collectors.maxBy(Comparator.naturalOrder()),
s -> s.max(Integer::compare));
assertCollect(data, Collectors.reducing(0, x -> x*2, Integer::sum),
s -> s.map(x -> x*2).reduce(0, Integer::sum));
assertCollect(data, Collectors.summingLong(x -> x * 2L),
s -> s.map(x -> x*2L).reduce(0L, Long::sum));
assertCollect(data, Collectors.summingInt(x -> x * 2),
s -> s.map(x -> x*2).reduce(0, Integer::sum));
assertCollect(data, Collectors.summingDouble(x -> x * 2.0d),
s -> s.map(x -> x * 2.0d).reduce(0.0d, Double::sum));
assertCollect(data, Collectors.averagingInt(x -> x * 2),
s -> s.mapToInt(x -> x * 2).average().orElse(0));
assertCollect(data, Collectors.averagingLong(x -> x * 2),
s -> s.mapToLong(x -> x * 2).average().orElse(0));
assertCollect(data, Collectors.averagingDouble(x -> x * 2),
s -> s.mapToDouble(x -> x * 2).average().orElse(0));
// Test explicit Collector.of
Collector<Integer, long[], Double> avg2xint = Collector.of(() -> new long[2],
(a, b) -> {
a[0] += b * 2;
a[1]++;
},
(a, b) -> {
a[0] += b[0];
a[1] += b[1];
return a;
},
a -> a[1] == 0 ? 0.0d : (double) a[0] / a[1]);
assertCollect(data, avg2xint,
s -> s.mapToInt(x -> x * 2).average().orElse(0));
}
@Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
public void testJoining(String name, TestData.OfRef<Integer> data) throws ReflectiveOperationException {
withData(data)
.terminal(s -> s.map(Object::toString).collect(Collectors.joining()))
.expectedResult(join(data, ""))
.exercise();
Collector<String, StringBuilder, String> likeJoining = Collector.of(StringBuilder::new, StringBuilder::append, (sb1, sb2) -> sb1.append(sb2.toString()), StringBuilder::toString);
withData(data)
.terminal(s -> s.map(Object::toString).collect(likeJoining))
.expectedResult(join(data, ""))
.exercise();
withData(data)
.terminal(s -> s.map(Object::toString).collect(Collectors.joining(",")))
.expectedResult(join(data, ","))
.exercise();
withData(data)
.terminal(s -> s.map(Object::toString).collect(Collectors.joining(",", "[", "]")))
.expectedResult("[" + join(data, ",") + "]")
.exercise();
withData(data)
.terminal(s -> s.map(Object::toString)
.collect(StringBuilder::new, StringBuilder::append, StringBuilder::append)
.toString())
.expectedResult(join(data, ""))
.exercise();
withData(data)
.terminal(s -> s.map(Object::toString)
.collect(() -> new StringJoiner(","),
(sj, cs) -> sj.add(cs),
(j1, j2) -> j1.merge(j2))
.toString())
.expectedResult(join(data, ","))
.exercise();
withData(data)
.terminal(s -> s.map(Object::toString)
.collect(() -> new StringJoiner(",", "[", "]"),
(sj, cs) -> sj.add(cs),
(j1, j2) -> j1.merge(j2))
.toString())
.expectedResult("[" + join(data, ",") + "]")
.exercise();
}
private<T> String join(TestData.OfRef<T> data, String delim) {
StringBuilder sb = new StringBuilder();
boolean first = true;
for (T i : data) {
if (!first)
sb.append(delim);
sb.append(i.toString());
first = false;
}
return sb.toString();
}
@Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
public void testSimpleToMap(String name, TestData.OfRef<Integer> data) throws ReflectiveOperationException {
Function<Integer, Integer> keyFn = i -> i * 2;
Function<Integer, Integer> valueFn = i -> i * 4;
List<Integer> dataAsList = Arrays.asList(data.stream().toArray(Integer[]::new));
Set<Integer> dataAsSet = new HashSet<>(dataAsList);
BinaryOperator<Integer> sum = Integer::sum;
for (BinaryOperator<Integer> op : Arrays.asList((u, v) -> u,
(u, v) -> v,
sum)) {
try {
exerciseMapCollection(data, toMap(keyFn, valueFn),
new ToMapAssertion<>(keyFn, valueFn, op, HashMap.class));
if (dataAsList.size() != dataAsSet.size())
fail("Expected ISE on input with duplicates");
}
catch (IllegalStateException e) {
if (dataAsList.size() == dataAsSet.size())
fail("Expected no ISE on input without duplicates");
}
exerciseMapCollection(data, toMap(keyFn, valueFn, op),
new ToMapAssertion<>(keyFn, valueFn, op, HashMap.class));
exerciseMapCollection(data, toMap(keyFn, valueFn, op, TreeMap::new),
new ToMapAssertion<>(keyFn, valueFn, op, TreeMap.class));
}
// For concurrent maps, only use commutative merge functions
try {
exerciseMapCollection(data, toConcurrentMap(keyFn, valueFn),
new ToMapAssertion<>(keyFn, valueFn, sum, ConcurrentHashMap.class));
if (dataAsList.size() != dataAsSet.size())
fail("Expected ISE on input with duplicates");
}
catch (IllegalStateException e) {
if (dataAsList.size() == dataAsSet.size())
fail("Expected no ISE on input without duplicates");
}
exerciseMapCollection(data, toConcurrentMap(keyFn, valueFn, sum),
new ToMapAssertion<>(keyFn, valueFn, sum, ConcurrentHashMap.class));
exerciseMapCollection(data, toConcurrentMap(keyFn, valueFn, sum, ConcurrentSkipListMap::new),
new ToMapAssertion<>(keyFn, valueFn, sum, ConcurrentSkipListMap.class));
}
@Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
public void testSimpleGroupingBy(String name, TestData.OfRef<Integer> data) throws ReflectiveOperationException {
Function<Integer, Integer> classifier = i -> i % 3;
// Single-level groupBy
exerciseMapCollection(data, groupingBy(classifier),
new GroupingByAssertion<>(classifier, HashMap.class,
new ToListAssertion<>()));
exerciseMapCollection(data, groupingByConcurrent(classifier),
new GroupingByAssertion<>(classifier, ConcurrentHashMap.class,
new ToListAssertion<>()));
// With explicit constructors
exerciseMapCollection(data,
groupingBy(classifier, TreeMap::new, toCollection(HashSet::new)),
new GroupingByAssertion<>(classifier, TreeMap.class,
new ToCollectionAssertion<Integer>(HashSet.class, false)));
exerciseMapCollection(data,
groupingByConcurrent(classifier, ConcurrentSkipListMap::new,
toCollection(HashSet::new)),
new GroupingByAssertion<>(classifier, ConcurrentSkipListMap.class,
new ToCollectionAssertion<Integer>(HashSet.class, false)));
}
@Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
public void testGroupingByWithMapping(String name, TestData.OfRef<Integer> data) throws ReflectiveOperationException {
Function<Integer, Integer> classifier = i -> i % 3;
Function<Integer, Integer> mapper = i -> i * 2;
exerciseMapCollection(data,
groupingBy(classifier, mapping(mapper, toList())),
new GroupingByAssertion<>(classifier, HashMap.class,
new MappingAssertion<>(mapper,
new ToListAssertion<>())));
}
@Test(groups = { "serialization-hostile" })
public void testFlatMappingClose() {
Function<Integer, Integer> classifier = i -> i;
AtomicInteger ai = new AtomicInteger();
Function<Integer, Stream<Integer>> flatMapper = i -> Stream.of(i, i).onClose(ai::getAndIncrement);
Map<Integer, List<Integer>> m = Stream.of(1, 2).collect(groupingBy(classifier, flatMapping(flatMapper, toList())));
assertEquals(m.size(), ai.get());
}
@Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
public void testGroupingByWithFlatMapping(String name, TestData.OfRef<Integer> data) throws ReflectiveOperationException {
Function<Integer, Integer> classifier = i -> i % 3;
Function<Integer, Stream<Integer>> flatMapperByNull = i -> null;
Function<Integer, Stream<Integer>> flatMapperBy0 = i -> Stream.empty();
Function<Integer, Stream<Integer>> flatMapperBy2 = i -> Stream.of(i, i);
exerciseMapCollection(data,
groupingBy(classifier, flatMapping(flatMapperByNull, toList())),
new GroupingByAssertion<>(classifier, HashMap.class,
new FlatMappingAssertion<>(flatMapperBy0,
new ToListAssertion<>())));
exerciseMapCollection(data,
groupingBy(classifier, flatMapping(flatMapperBy0, toList())),
new GroupingByAssertion<>(classifier, HashMap.class,
new FlatMappingAssertion<>(flatMapperBy0,
new ToListAssertion<>())));
exerciseMapCollection(data,
groupingBy(classifier, flatMapping(flatMapperBy2, toList())),
new GroupingByAssertion<>(classifier, HashMap.class,
new FlatMappingAssertion<>(flatMapperBy2,
new ToListAssertion<>())));
}
@Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
public void testGroupingByWithFiltering(String name, TestData.OfRef<Integer> data) throws ReflectiveOperationException {
Function<Integer, Integer> classifier = i -> i % 3;
Predicate<Integer> filteringByMod2 = i -> i % 2 == 0;
Predicate<Integer> filteringByUnder100 = i -> i % 2 < 100;
Predicate<Integer> filteringByTrue = i -> true;
Predicate<Integer> filteringByFalse = i -> false;
exerciseMapCollection(data,
groupingBy(classifier, filtering(filteringByMod2, toList())),
new GroupingByAssertion<>(classifier, HashMap.class,
new FilteringAssertion<>(filteringByMod2,
new ToListAssertion<>())));
exerciseMapCollection(data,
groupingBy(classifier, filtering(filteringByUnder100, toList())),
new GroupingByAssertion<>(classifier, HashMap.class,
new FilteringAssertion<>(filteringByUnder100,
new ToListAssertion<>())));
exerciseMapCollection(data,
groupingBy(classifier, filtering(filteringByTrue, toList())),
new GroupingByAssertion<>(classifier, HashMap.class,
new FilteringAssertion<>(filteringByTrue,
new ToListAssertion<>())));
exerciseMapCollection(data,
groupingBy(classifier, filtering(filteringByFalse, toList())),
new GroupingByAssertion<>(classifier, HashMap.class,
new FilteringAssertion<>(filteringByFalse,
new ToListAssertion<>())));
}
@Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
public void testTwoLevelGroupingBy(String name, TestData.OfRef<Integer> data) throws ReflectiveOperationException {
Function<Integer, Integer> classifier = i -> i % 6;
Function<Integer, Integer> classifier2 = i -> i % 23;
// Two-level groupBy
exerciseMapCollection(data,
groupingBy(classifier, groupingBy(classifier2)),
new GroupingByAssertion<>(classifier, HashMap.class,
new GroupingByAssertion<>(classifier2, HashMap.class,
new ToListAssertion<>())));
// with concurrent as upstream
exerciseMapCollection(data,
groupingByConcurrent(classifier, groupingBy(classifier2)),
new GroupingByAssertion<>(classifier, ConcurrentHashMap.class,
new GroupingByAssertion<>(classifier2, HashMap.class,
new ToListAssertion<>())));
// with concurrent as downstream
exerciseMapCollection(data,
groupingBy(classifier, groupingByConcurrent(classifier2)),
new GroupingByAssertion<>(classifier, HashMap.class,
new GroupingByAssertion<>(classifier2, ConcurrentHashMap.class,
new ToListAssertion<>())));
// with concurrent as upstream and downstream
exerciseMapCollection(data,
groupingByConcurrent(classifier, groupingByConcurrent(classifier2)),
new GroupingByAssertion<>(classifier, ConcurrentHashMap.class,
new GroupingByAssertion<>(classifier2, ConcurrentHashMap.class,
new ToListAssertion<>())));
// With explicit constructors
exerciseMapCollection(data,
groupingBy(classifier, TreeMap::new, groupingBy(classifier2, TreeMap::new, toCollection(HashSet::new))),
new GroupingByAssertion<>(classifier, TreeMap.class,
new GroupingByAssertion<>(classifier2, TreeMap.class,
new ToCollectionAssertion<Integer>(HashSet.class, false))));
// with concurrent as upstream
exerciseMapCollection(data,
groupingByConcurrent(classifier, ConcurrentSkipListMap::new, groupingBy(classifier2, TreeMap::new, toList())),
new GroupingByAssertion<>(classifier, ConcurrentSkipListMap.class,
new GroupingByAssertion<>(classifier2, TreeMap.class,
new ToListAssertion<>())));
// with concurrent as downstream
exerciseMapCollection(data,
groupingBy(classifier, TreeMap::new, groupingByConcurrent(classifier2, ConcurrentSkipListMap::new, toList())),
new GroupingByAssertion<>(classifier, TreeMap.class,
new GroupingByAssertion<>(classifier2, ConcurrentSkipListMap.class,
new ToListAssertion<>())));
// with concurrent as upstream and downstream
exerciseMapCollection(data,
groupingByConcurrent(classifier, ConcurrentSkipListMap::new, groupingByConcurrent(classifier2, ConcurrentSkipListMap::new, toList())),
new GroupingByAssertion<>(classifier, ConcurrentSkipListMap.class,
new GroupingByAssertion<>(classifier2, ConcurrentSkipListMap.class,
new ToListAssertion<>())));
}
@Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
public void testGroupubgByWithReducing(String name, TestData.OfRef<Integer> data) throws ReflectiveOperationException {
Function<Integer, Integer> classifier = i -> i % 3;
// Single-level simple reduce
exerciseMapCollection(data,
groupingBy(classifier, reducing(0, Integer::sum)),
new GroupingByAssertion<>(classifier, HashMap.class,
new ReducingAssertion<>(0, LambdaTestHelpers.identity(), Integer::sum)));
// with concurrent
exerciseMapCollection(data,
groupingByConcurrent(classifier, reducing(0, Integer::sum)),
new GroupingByAssertion<>(classifier, ConcurrentHashMap.class,
new ReducingAssertion<>(0, LambdaTestHelpers.identity(), Integer::sum)));
// With explicit constructors
exerciseMapCollection(data,
groupingBy(classifier, TreeMap::new, reducing(0, Integer::sum)),
new GroupingByAssertion<>(classifier, TreeMap.class,
new ReducingAssertion<>(0, LambdaTestHelpers.identity(), Integer::sum)));
// with concurrent
exerciseMapCollection(data,
groupingByConcurrent(classifier, ConcurrentSkipListMap::new, reducing(0, Integer::sum)),
new GroupingByAssertion<>(classifier, ConcurrentSkipListMap.class,
new ReducingAssertion<>(0, LambdaTestHelpers.identity(), Integer::sum)));
// Single-level map-reduce
exerciseMapCollection(data,
groupingBy(classifier, reducing(0, mDoubler, Integer::sum)),
new GroupingByAssertion<>(classifier, HashMap.class,
new ReducingAssertion<>(0, mDoubler, Integer::sum)));
// with concurrent
exerciseMapCollection(data,
groupingByConcurrent(classifier, reducing(0, mDoubler, Integer::sum)),
new GroupingByAssertion<>(classifier, ConcurrentHashMap.class,
new ReducingAssertion<>(0, mDoubler, Integer::sum)));
// With explicit constructors
exerciseMapCollection(data,
groupingBy(classifier, TreeMap::new, reducing(0, mDoubler, Integer::sum)),
new GroupingByAssertion<>(classifier, TreeMap.class,
new ReducingAssertion<>(0, mDoubler, Integer::sum)));
// with concurrent
exerciseMapCollection(data,
groupingByConcurrent(classifier, ConcurrentSkipListMap::new, reducing(0, mDoubler, Integer::sum)),
new GroupingByAssertion<>(classifier, ConcurrentSkipListMap.class,
new ReducingAssertion<>(0, mDoubler, Integer::sum)));
}
@Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
public void testSimplePartitioningBy(String name, TestData.OfRef<Integer> data) throws ReflectiveOperationException {
Predicate<Integer> classifier = i -> i % 3 == 0;
// Single-level partition to downstream List
exerciseMapCollection(data,
partitioningBy(classifier),
new PartitioningByAssertion<>(classifier, new ToListAssertion<>()));
exerciseMapCollection(data,
partitioningBy(classifier, toList()),
new PartitioningByAssertion<>(classifier, new ToListAssertion<>()));
}
@Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
public void testTwoLevelPartitioningBy(String name, TestData.OfRef<Integer> data) throws ReflectiveOperationException {
Predicate<Integer> classifier = i -> i % 3 == 0;
Predicate<Integer> classifier2 = i -> i % 7 == 0;
// Two level partition
exerciseMapCollection(data,
partitioningBy(classifier, partitioningBy(classifier2)),
new PartitioningByAssertion<>(classifier,
new PartitioningByAssertion(classifier2, new ToListAssertion<>())));
// Two level partition with reduce
exerciseMapCollection(data,
partitioningBy(classifier, reducing(0, Integer::sum)),
new PartitioningByAssertion<>(classifier,
new ReducingAssertion<>(0, LambdaTestHelpers.identity(), Integer::sum)));
}
@Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
public void testComposeFinisher(String name, TestData.OfRef<Integer> data) throws ReflectiveOperationException {
List<Integer> asList = exerciseTerminalOps(data, s -> s.collect(toList()));
List<Integer> asImmutableList = exerciseTerminalOps(data, s -> s.collect(collectingAndThen(toList(), Collections::unmodifiableList)));
assertEquals(asList, asImmutableList);
try {
asImmutableList.add(0);
fail("Expecting immutable result");
}
catch (UnsupportedOperationException ignored) { }
}
@Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
public void testTeeing(String name, TestData.OfRef<Integer> data) throws ReflectiveOperationException {
Collector<Integer, ?, Long> summing = Collectors.summingLong(Integer::valueOf);
Collector<Integer, ?, Long> counting = Collectors.counting();
Collector<Integer, ?, Integer> min = collectingAndThen(Collectors.<Integer>minBy(Comparator.naturalOrder()),
opt -> opt.orElse(Integer.MAX_VALUE));
Collector<Integer, ?, Integer> max = collectingAndThen(Collectors.<Integer>maxBy(Comparator.naturalOrder()),
opt -> opt.orElse(Integer.MIN_VALUE));
Collector<Integer, ?, String> joining = mapping(String::valueOf, Collectors.joining(", ", "[", "]"));
Collector<Integer, ?, Map.Entry<Long, Long>> sumAndCount = Collectors.teeing(summing, counting, Map::entry);
Collector<Integer, ?, Map.Entry<Integer, Integer>> minAndMax = Collectors.teeing(min, max, Map::entry);
Collector<Integer, ?, Double> averaging = Collectors.teeing(summing, counting,
(sum, count) -> ((double)sum) / count);
Collector<Integer, ?, String> summaryStatistics = Collectors.teeing(sumAndCount, minAndMax,
(sumCountEntry, minMaxEntry) -> new IntSummaryStatistics(
sumCountEntry.getValue(), minMaxEntry.getKey(),
minMaxEntry.getValue(), sumCountEntry.getKey()).toString());
Collector<Integer, ?, String> countAndContent = Collectors.teeing(counting, joining,
(count, content) -> count+": "+content);
assertCollect(data, sumAndCount, stream -> {
List<Integer> list = stream.collect(toList());
return Map.entry(list.stream().mapToLong(Integer::intValue).sum(), (long) list.size());
});
assertCollect(data, averaging, stream -> stream.mapToInt(Integer::intValue).average().orElse(Double.NaN));
assertCollect(data, summaryStatistics,
stream -> stream.mapToInt(Integer::intValue).summaryStatistics().toString());
assertCollect(data, countAndContent, stream -> {
List<Integer> list = stream.collect(toList());
return list.size()+": "+list;
});
Function<Integer, Integer> classifier = i -> i % 3;
exerciseMapCollection(data, groupingBy(classifier, sumAndCount),
new GroupingByAssertion<>(classifier, Map.class,
new TeeingAssertion<>(summing, counting, Map::entry)));
}
}

View file

@ -0,0 +1,142 @@
/*
* Copyright (c) 2012, 2013, 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.
*/
package org.openjdk.tests.java.util.stream;
import java.util.Spliterator;
import java.util.stream.BaseStream;
import java.util.stream.OpTestCase;
import java.util.stream.StreamTestDataProvider;
import org.testng.annotations.Test;
import java.util.stream.Stream;
import java.util.stream.IntStream;
import java.util.stream.LongStream;
import java.util.stream.DoubleStream;
import java.util.stream.TestData;
import static java.util.stream.LambdaTestHelpers.*;
import static org.testng.Assert.assertEquals;
/**
* @test
* @bug 8021863
*/
public class ConcatOpTest extends OpTestCase {
// Sanity to make sure all type of stream source works
@Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
public void testOps(String name, TestData.OfRef<Integer> data) {
exerciseOpsInt(data,
s -> Stream.concat(s, data.stream()),
s -> IntStream.concat(s, data.stream().mapToInt(Integer::intValue)),
s -> LongStream.concat(s, data.stream().mapToLong(Integer::longValue)),
s -> DoubleStream.concat(s, data.stream().mapToDouble(Integer::doubleValue)));
}
public void testSize() {
assertSized(Stream.concat(
LongStream.range(0, Long.MAX_VALUE / 2).boxed(),
LongStream.range(0, Long.MAX_VALUE / 2).boxed()));
assertUnsized(Stream.concat(
LongStream.range(0, Long.MAX_VALUE).boxed(),
LongStream.range(0, Long.MAX_VALUE).boxed()));
assertUnsized(Stream.concat(
LongStream.range(0, Long.MAX_VALUE).boxed(),
Stream.iterate(0, i -> i + 1)));
assertUnsized(Stream.concat(
Stream.iterate(0, i -> i + 1),
LongStream.range(0, Long.MAX_VALUE).boxed()));
}
public void testLongSize() {
assertSized(LongStream.concat(
LongStream.range(0, Long.MAX_VALUE / 2),
LongStream.range(0, Long.MAX_VALUE / 2)));
assertUnsized(LongStream.concat(
LongStream.range(0, Long.MAX_VALUE),
LongStream.range(0, Long.MAX_VALUE)));
assertUnsized(LongStream.concat(
LongStream.range(0, Long.MAX_VALUE),
LongStream.iterate(0, i -> i + 1)));
assertUnsized(LongStream.concat(
LongStream.iterate(0, i -> i + 1),
LongStream.range(0, Long.MAX_VALUE)));
}
public void testIntSize() {
assertSized(IntStream.concat(
IntStream.range(0, Integer.MAX_VALUE),
IntStream.range(0, Integer.MAX_VALUE)));
assertUnsized(IntStream.concat(
LongStream.range(0, Long.MAX_VALUE).mapToInt(i -> (int) i),
LongStream.range(0, Long.MAX_VALUE).mapToInt(i -> (int) i)));
assertUnsized(IntStream.concat(
LongStream.range(0, Long.MAX_VALUE).mapToInt(i -> (int) i),
IntStream.iterate(0, i -> i + 1)));
assertUnsized(IntStream.concat(
IntStream.iterate(0, i -> i + 1),
LongStream.range(0, Long.MAX_VALUE).mapToInt(i -> (int) i)));
}
public void testDoubleSize() {
assertSized(DoubleStream.concat(
IntStream.range(0, Integer.MAX_VALUE).mapToDouble(i -> i),
IntStream.range(0, Integer.MAX_VALUE).mapToDouble(i -> i)));
assertUnsized(DoubleStream.concat(
LongStream.range(0, Long.MAX_VALUE).mapToDouble(i -> i),
LongStream.range(0, Long.MAX_VALUE).mapToDouble(i -> i)));
assertUnsized(DoubleStream.concat(
LongStream.range(0, Long.MAX_VALUE).mapToDouble(i -> i),
DoubleStream.iterate(0, i -> i + 1)));
assertUnsized(DoubleStream.concat(
DoubleStream.iterate(0, i -> i + 1),
LongStream.range(0, Long.MAX_VALUE).mapToDouble(i -> i)));
}
void assertUnsized(BaseStream<?, ?> s) {
Spliterator<?> sp = s.spliterator();
assertFalse(sp.hasCharacteristics(Spliterator.SIZED | Spliterator.SUBSIZED));
assertEquals(sp.estimateSize(), Long.MAX_VALUE);
}
void assertSized(BaseStream<?, ?> s) {
Spliterator<?> sp = s.spliterator();
assertTrue(sp.hasCharacteristics(Spliterator.SIZED | Spliterator.SUBSIZED));
assertTrue(sp.estimateSize() < Long.MAX_VALUE);
}
}

View file

@ -0,0 +1,229 @@
/*
* Copyright (c) 2012, 2013, 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.
*/
package org.openjdk.tests.java.util.stream;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Factory;
import org.testng.annotations.Test;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Spliterator;
import java.util.TreeSet;
import java.util.stream.DoubleStream;
import java.util.stream.IntStream;
import java.util.stream.LongStream;
import java.util.stream.Stream;
import static java.util.stream.LambdaTestHelpers.*;
import static org.testng.Assert.*;
@Test
public class ConcatTest {
private static Object[][] cases;
static {
List<Integer> part1 = Arrays.asList(5, 3, 4, 1, 2, 6, 2, 4);
List<Integer> part2 = Arrays.asList(8, 8, 6, 6, 9, 7, 10, 9);
List<Integer> p1p2 = Arrays.asList(5, 3, 4, 1, 2, 6, 2, 4, 8, 8, 6, 6, 9, 7, 10, 9);
List<Integer> p2p1 = Arrays.asList(8, 8, 6, 6, 9, 7, 10, 9, 5, 3, 4, 1, 2, 6, 2, 4);
List<Integer> empty = new LinkedList<>(); // To be ordered
assertTrue(empty.isEmpty());
LinkedHashSet<Integer> distinctP1 = new LinkedHashSet<>(part1);
LinkedHashSet<Integer> distinctP2 = new LinkedHashSet<>(part2);
TreeSet<Integer> sortedP1 = new TreeSet<>(part1);
TreeSet<Integer> sortedP2 = new TreeSet<>(part2);
cases = new Object[][] {
{ "regular", part1, part2, p1p2 },
{ "reverse regular", part2, part1, p2p1 },
{ "front distinct", distinctP1, part2, Arrays.asList(5, 3, 4, 1, 2, 6, 8, 8, 6, 6, 9, 7, 10, 9) },
{ "back distinct", part1, distinctP2, Arrays.asList(5, 3, 4, 1, 2, 6, 2, 4, 8, 6, 9, 7, 10) },
{ "both distinct", distinctP1, distinctP2, Arrays.asList(5, 3, 4, 1, 2, 6, 8, 6, 9, 7, 10) },
{ "front sorted", sortedP1, part2, Arrays.asList(1, 2, 3, 4, 5, 6, 8, 8, 6, 6, 9, 7, 10, 9) },
{ "back sorted", part1, sortedP2, Arrays.asList(5, 3, 4, 1, 2, 6, 2, 4, 6, 7, 8, 9, 10) },
{ "both sorted", sortedP1, sortedP2, Arrays.asList(1, 2, 3, 4, 5, 6, 6, 7, 8, 9, 10) },
{ "reverse both sorted", sortedP2, sortedP1, Arrays.asList(6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6) },
{ "empty something", empty, part1, part1 },
{ "something empty", part1, empty, part1 },
{ "empty empty", empty, empty, empty }
};
}
@DataProvider(name = "cases")
private static Object[][] getCases() {
return cases;
}
@Factory(dataProvider = "cases")
public static Object[] createTests(String scenario, Collection<Integer> c1, Collection<Integer> c2, Collection<Integer> expected) {
return new Object[] {
new ConcatTest(scenario, c1, c2, expected)
};
}
protected final String scenario;
protected final Collection<Integer> c1;
protected final Collection<Integer> c2;
protected final Collection<Integer> expected;
public ConcatTest(String scenario, Collection<Integer> c1, Collection<Integer> c2, Collection<Integer> expected) {
this.scenario = scenario;
this.c1 = c1;
this.c2 = c2;
this.expected = expected;
// verify prerequisite
Stream<Integer> s1s = c1.stream();
Stream<Integer> s2s = c2.stream();
Stream<Integer> s1p = c1.parallelStream();
Stream<Integer> s2p = c2.parallelStream();
assertTrue(s1p.isParallel());
assertTrue(s2p.isParallel());
assertFalse(s1s.isParallel());
assertFalse(s2s.isParallel());
assertTrue(s1s.spliterator().hasCharacteristics(Spliterator.ORDERED));
assertTrue(s1p.spliterator().hasCharacteristics(Spliterator.ORDERED));
assertTrue(s2s.spliterator().hasCharacteristics(Spliterator.ORDERED));
assertTrue(s2p.spliterator().hasCharacteristics(Spliterator.ORDERED));
}
private <T> void assertConcatContent(Spliterator<T> sp, boolean ordered, Spliterator<T> expected) {
// concat stream cannot guarantee uniqueness
assertFalse(sp.hasCharacteristics(Spliterator.DISTINCT), scenario);
// concat stream cannot guarantee sorted
assertFalse(sp.hasCharacteristics(Spliterator.SORTED), scenario);
// concat stream is ordered if both are ordered
assertEquals(sp.hasCharacteristics(Spliterator.ORDERED), ordered, scenario);
// Verify elements
if (ordered) {
assertEquals(toBoxedList(sp),
toBoxedList(expected),
scenario);
} else {
assertEquals(toBoxedMultiset(sp),
toBoxedMultiset(expected),
scenario);
}
}
private void assertRefConcat(Stream<Integer> s1, Stream<Integer> s2, boolean parallel, boolean ordered) {
Stream<Integer> result = Stream.concat(s1, s2);
assertEquals(result.isParallel(), parallel);
assertConcatContent(result.spliterator(), ordered, expected.spliterator());
}
private void assertIntConcat(Stream<Integer> s1, Stream<Integer> s2, boolean parallel, boolean ordered) {
IntStream result = IntStream.concat(s1.mapToInt(Integer::intValue),
s2.mapToInt(Integer::intValue));
assertEquals(result.isParallel(), parallel);
assertConcatContent(result.spliterator(), ordered,
expected.stream().mapToInt(Integer::intValue).spliterator());
}
private void assertLongConcat(Stream<Integer> s1, Stream<Integer> s2, boolean parallel, boolean ordered) {
LongStream result = LongStream.concat(s1.mapToLong(Integer::longValue),
s2.mapToLong(Integer::longValue));
assertEquals(result.isParallel(), parallel);
assertConcatContent(result.spliterator(), ordered,
expected.stream().mapToLong(Integer::longValue).spliterator());
}
private void assertDoubleConcat(Stream<Integer> s1, Stream<Integer> s2, boolean parallel, boolean ordered) {
DoubleStream result = DoubleStream.concat(s1.mapToDouble(Integer::doubleValue),
s2.mapToDouble(Integer::doubleValue));
assertEquals(result.isParallel(), parallel);
assertConcatContent(result.spliterator(), ordered,
expected.stream().mapToDouble(Integer::doubleValue).spliterator());
}
public void testRefConcat() {
// sequential + sequential -> sequential
assertRefConcat(c1.stream(), c2.stream(), false, true);
// parallel + parallel -> parallel
assertRefConcat(c1.parallelStream(), c2.parallelStream(), true, true);
// sequential + parallel -> parallel
assertRefConcat(c1.stream(), c2.parallelStream(), true, true);
// parallel + sequential -> parallel
assertRefConcat(c1.parallelStream(), c2.stream(), true, true);
// not ordered
assertRefConcat(c1.stream().unordered(), c2.stream(), false, false);
assertRefConcat(c1.stream(), c2.stream().unordered(), false, false);
assertRefConcat(c1.parallelStream().unordered(), c2.stream().unordered(), true, false);
}
public void testIntConcat() {
// sequential + sequential -> sequential
assertIntConcat(c1.stream(), c2.stream(), false, true);
// parallel + parallel -> parallel
assertIntConcat(c1.parallelStream(), c2.parallelStream(), true, true);
// sequential + parallel -> parallel
assertIntConcat(c1.stream(), c2.parallelStream(), true, true);
// parallel + sequential -> parallel
assertIntConcat(c1.parallelStream(), c2.stream(), true, true);
// not ordered
assertIntConcat(c1.stream().unordered(), c2.stream(), false, false);
assertIntConcat(c1.stream(), c2.stream().unordered(), false, false);
assertIntConcat(c1.parallelStream().unordered(), c2.stream().unordered(), true, false);
}
public void testLongConcat() {
// sequential + sequential -> sequential
assertLongConcat(c1.stream(), c2.stream(), false, true);
// parallel + parallel -> parallel
assertLongConcat(c1.parallelStream(), c2.parallelStream(), true, true);
// sequential + parallel -> parallel
assertLongConcat(c1.stream(), c2.parallelStream(), true, true);
// parallel + sequential -> parallel
assertLongConcat(c1.parallelStream(), c2.stream(), true, true);
// not ordered
assertLongConcat(c1.stream().unordered(), c2.stream(), false, false);
assertLongConcat(c1.stream(), c2.stream().unordered(), false, false);
assertLongConcat(c1.parallelStream().unordered(), c2.stream().unordered(), true, false);
}
public void testDoubleConcat() {
// sequential + sequential -> sequential
assertDoubleConcat(c1.stream(), c2.stream(), false, true);
// parallel + parallel -> parallel
assertDoubleConcat(c1.parallelStream(), c2.parallelStream(), true, true);
// sequential + parallel -> parallel
assertDoubleConcat(c1.stream(), c2.parallelStream(), true, true);
// parallel + sequential -> parallel
assertDoubleConcat(c1.parallelStream(), c2.stream(), true, true);
// not ordered
assertDoubleConcat(c1.stream().unordered(), c2.stream(), false, false);
assertDoubleConcat(c1.stream(), c2.stream().unordered(), false, false);
assertDoubleConcat(c1.parallelStream().unordered(), c2.stream().unordered(), true, false);
}
}

View file

@ -0,0 +1,102 @@
/*
* Copyright (c) 2014, 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
* 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
* @summary Tests counting of streams containing Integer.MAX_VALUE + 1 elements
* @bug 8031187 8067969
*/
package org.openjdk.tests.java.util.stream;
import java.util.stream.LongStream;
import org.testng.annotations.Test;
import static org.testng.Assert.*;
@Test
public class CountLargeTest {
static final long EXPECTED_LARGE_COUNT = 1L + Integer.MAX_VALUE;
public void testRefLarge() {
// Test known sized stream
{
long count = LongStream.range(0, EXPECTED_LARGE_COUNT)
.mapToObj(e -> null).count();
assertEquals(count, EXPECTED_LARGE_COUNT);
}
// Test unknown sized stream
{
long count = LongStream.range(0, EXPECTED_LARGE_COUNT)
.mapToObj(e -> null).filter(e -> true).count();
assertEquals(count, EXPECTED_LARGE_COUNT);
}
}
public void testIntLarge() {
// Test known sized stream
{
long count = LongStream.range(0, EXPECTED_LARGE_COUNT)
.mapToInt(e -> 0).count();
assertEquals(count, EXPECTED_LARGE_COUNT);
}
// Test unknown sized stream
{
long count = LongStream.range(0, EXPECTED_LARGE_COUNT)
.mapToInt(e -> 0).filter(e -> true).count();
assertEquals(count, EXPECTED_LARGE_COUNT);
}
}
public void testLongLarge() {
// Test known sized stream
{
long count = LongStream.range(0, EXPECTED_LARGE_COUNT)
.count();
assertEquals(count, EXPECTED_LARGE_COUNT);
}
// Test unknown sized stream
{
long count = LongStream.range(0, EXPECTED_LARGE_COUNT)
.filter(e -> true).count();
assertEquals(count, EXPECTED_LARGE_COUNT);
}
}
public void testDoubleLarge() {
// Test known sized stream
{
long count = LongStream.range(0, EXPECTED_LARGE_COUNT)
.mapToDouble(e -> 0.0).count();
assertEquals(count, EXPECTED_LARGE_COUNT);
}
// Test unknown sized stream
{
long count = LongStream.range(0, EXPECTED_LARGE_COUNT)
.mapToDouble(e -> 0.0).filter(e -> true).count();
assertEquals(count, EXPECTED_LARGE_COUNT);
}
}
}

View file

@ -0,0 +1,228 @@
/*
* Copyright (c) 2014, 2021, 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
* @summary Tests counting of streams
* @bug 8031187 8067969 8075307 8265029
*/
package org.openjdk.tests.java.util.stream;
import java.util.HashSet;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import java.util.stream.DoubleStream;
import java.util.stream.DoubleStreamTestDataProvider;
import java.util.stream.IntStream;
import java.util.stream.IntStreamTestDataProvider;
import java.util.stream.LongStream;
import java.util.stream.LongStreamTestDataProvider;
import java.util.stream.OpTestCase;
import java.util.stream.Stream;
import java.util.stream.StreamTestDataProvider;
import java.util.stream.TestData;
import org.testng.annotations.Test;
public class CountTest extends OpTestCase {
@Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
public void testOps(String name, TestData.OfRef<Integer> data) {
long expectedCount = data.size();
withData(data).
terminal(Stream::count).
expectedResult(expectedCount).
exercise();
withData(data).
terminal(s -> s.skip(1), Stream::count).
expectedResult(Math.max(0, expectedCount - 1)).
exercise();
// Test with an unknown sized stream
withData(data).
terminal(s -> s.filter(e -> true), Stream::count).
expectedResult(expectedCount).
exercise();
// Test counting collector
withData(data).
terminal(s -> s, s -> s.collect(Collectors.counting())).
expectedResult(expectedCount).
exercise();
// Test with stateful distinct op that is a barrier or lazy
// depending if source is not already distinct and encounter order is
// preserved or not
expectedCount = data.into(new HashSet<>()).size();
withData(data).
terminal(Stream::distinct, Stream::count).
expectedResult(expectedCount).
exercise();
withData(data).
terminal(s -> s.unordered().distinct(), Stream::count).
expectedResult(expectedCount).
exercise();
}
@Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
public void testOps(String name, TestData.OfInt data) {
long expectedCount = data.size();
withData(data).
terminal(IntStream::count).
expectedResult(expectedCount).
exercise();
withData(data).
terminal(s -> s.skip(1), IntStream::count).
expectedResult(Math.max(0, expectedCount - 1)).
exercise();
withData(data).
terminal(s -> s.filter(e -> true), IntStream::count).
expectedResult(expectedCount).
exercise();
expectedCount = data.into(new HashSet<>()).size();
withData(data).
terminal(IntStream::distinct, IntStream::count).
expectedResult(expectedCount).
exercise();
withData(data).
terminal(s -> s.unordered().distinct(), IntStream::count).
expectedResult(expectedCount).
exercise();
}
@Test(dataProvider = "LongStreamTestData", dataProviderClass = LongStreamTestDataProvider.class)
public void testOps(String name, TestData.OfLong data) {
long expectedCount = data.size();
withData(data).
terminal(LongStream::count).
expectedResult(expectedCount).
exercise();
withData(data).
terminal(s -> s.skip(1), LongStream::count).
expectedResult(Math.max(0, expectedCount - 1)).
exercise();
withData(data).
terminal(s -> s.filter(e -> true), LongStream::count).
expectedResult(expectedCount).
exercise();
expectedCount = data.into(new HashSet<>()).size();
withData(data).
terminal(LongStream::distinct, LongStream::count).
expectedResult(expectedCount).
exercise();
withData(data).
terminal(s -> s.unordered().distinct(), LongStream::count).
expectedResult(expectedCount).
exercise();
}
@Test(dataProvider = "DoubleStreamTestData", dataProviderClass = DoubleStreamTestDataProvider.class)
public void testOps(String name, TestData.OfDouble data) {
long expectedCount = data.size();
withData(data).
terminal(DoubleStream::count).
expectedResult(expectedCount).
exercise();
withData(data).
terminal(s -> s.skip(1), DoubleStream::count).
expectedResult(Math.max(0, expectedCount - 1)).
exercise();
withData(data).
terminal(s -> s.filter(e -> true), DoubleStream::count).
expectedResult(expectedCount).
exercise();
expectedCount = data.into(new HashSet<>()).size();
withData(data).
terminal(DoubleStream::distinct, DoubleStream::count).
expectedResult(expectedCount).
exercise();
withData(data).
terminal(s -> s.unordered().distinct(), DoubleStream::count).
expectedResult(expectedCount).
exercise();
}
@Test
public void testNoEvaluationForSizedStream() {
checkStreamDoesNotConsumeElements(() -> Stream.of(1, 2, 3, 4), 4);
checkStreamDoesNotConsumeElements(() -> Stream.of(1, 2, 3, 4).skip(1).limit(2).skip(1), 1);
checkIntStreamDoesNotConsumeElements(() -> IntStream.of(1, 2, 3, 4), 4);
checkIntStreamDoesNotConsumeElements(() -> IntStream.of(1, 2, 3, 4).skip(1).limit(2).skip(1), 1);
checkLongStreamDoesNotConsumeElements(() -> LongStream.of(1, 2, 3, 4), 4);
checkLongStreamDoesNotConsumeElements(() -> LongStream.of(1, 2, 3, 4).skip(1).limit(2).skip(1), 1);
checkDoubleStreamDoesNotConsumeElements(() -> DoubleStream.of(1, 2, 3, 4), 4);
checkDoubleStreamDoesNotConsumeElements(() -> DoubleStream.of(1, 2, 3, 4).skip(1).limit(2).skip(1), 1);
}
private void checkStreamDoesNotConsumeElements(Supplier<Stream<?>> supplier, long expectedCount) {
AtomicInteger ai = new AtomicInteger();
assertEquals(supplier.get().peek(e -> ai.getAndIncrement()).count(), expectedCount);
assertEquals(ai.get(), 0);
assertEquals(supplier.get().peek(e -> ai.getAndIncrement()).parallel().count(), expectedCount);
assertEquals(ai.get(), 0);
}
private void checkIntStreamDoesNotConsumeElements(Supplier<IntStream> supplier, long expectedCount) {
AtomicInteger ai = new AtomicInteger();
assertEquals(supplier.get().peek(e -> ai.getAndIncrement()).count(), expectedCount);
assertEquals(ai.get(), 0);
assertEquals(supplier.get().peek(e -> ai.getAndIncrement()).parallel().count(), expectedCount);
assertEquals(ai.get(), 0);
}
private void checkLongStreamDoesNotConsumeElements(Supplier<LongStream> supplier, long expectedCount) {
AtomicInteger ai = new AtomicInteger();
assertEquals(supplier.get().peek(e -> ai.getAndIncrement()).count(), expectedCount);
assertEquals(ai.get(), 0);
assertEquals(supplier.get().peek(e -> ai.getAndIncrement()).parallel().count(), expectedCount);
assertEquals(ai.get(), 0);
}
private void checkDoubleStreamDoesNotConsumeElements(Supplier<DoubleStream> supplier, long expectedCount) {
AtomicInteger ai = new AtomicInteger();
assertEquals(supplier.get().peek(e -> ai.getAndIncrement()).count(), expectedCount);
assertEquals(ai.get(), 0);
assertEquals(supplier.get().peek(e -> ai.getAndIncrement()).parallel().count(), expectedCount);
assertEquals(ai.get(), 0);
}
}

View file

@ -0,0 +1,200 @@
/*
* Copyright (c) 2012, 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
* 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.
*/
package org.openjdk.tests.java.util.stream;
import org.testng.annotations.Test;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import java.util.Spliterator;
import java.util.Spliterators;
import java.util.concurrent.ThreadLocalRandom;
import java.util.stream.CollectorOps;
import java.util.stream.Collectors;
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.StreamSupport;
import java.util.stream.StreamTestDataProvider;
import java.util.stream.TestData;
import static java.util.stream.LambdaTestHelpers.*;
/**
* DistinctOpTest
*/
@Test
public class DistinctOpTest extends OpTestCase {
public void testUniqOp() {
assertCountSum(repeat(0, 10).stream().distinct(), 1, 0);
assertCountSum(repeat(1, 10).stream().distinct(), 1, 1);
assertCountSum(countTo(0).stream().distinct(), 0, 0);
assertCountSum(countTo(10).stream().distinct(), 10, 55);
assertCountSum(countTo(10).stream().distinct(), 10, 55);
}
public void testWithUnorderedInfiniteStream() {
// These tests should short-circuit, otherwise will fail with a time-out
// or an OOME
// Note that since the streams are unordered and any element is requested
// (a non-deterministic process) the only assertion that can be made is
// that an element should be found
Optional<Integer> oi = Stream.iterate(1, i -> i + 1).unordered().parallel().distinct().findAny();
assertTrue(oi.isPresent());
oi = ThreadLocalRandom.current().ints().boxed().parallel().distinct().findAny();
assertTrue(oi.isPresent());
}
@Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
public void testOp(String name, TestData.OfRef<Integer> data) {
Collection<Integer> result = exerciseOpsInt(
data,
Stream::distinct,
IntStream::distinct,
LongStream::distinct,
DoubleStream::distinct);
assertUnique(result);
assertTrue((data.size() > 0) ? result.size() > 0 : result.size() == 0);
assertTrue(result.size() <= data.size());
}
@Test(dataProvider = "withNull:StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
public void testOpWithNull(String name, TestData.OfRef<Integer> data) {
Collection<Integer> node = exerciseOps(data, Stream::distinct);
assertUnique(node);
node = withData(data).
stream(s -> s.unordered().distinct()).
exercise();
assertUnique(node);
node = exerciseOps(data, s -> s.distinct().distinct());
assertUnique(node);
}
@Test(dataProvider = "withNull:StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
public void testOpWithNullSorted(String name, TestData.OfRef<Integer> data) {
List<Integer> l = new ArrayList<>();
data.into(l).sort(cNullInteger);
// Need to inject SORTED into the sorted list source since
// sorted() with a comparator ironically clears SORTED
Collection<Integer> node = exerciseOps(new SortedTestData<>(l), Stream::distinct);
assertUnique(node);
assertSorted(node, cNullInteger);
}
@SuppressWarnings("serial")
static class SortedTestData<T> extends TestData.AbstractTestData.RefTestData<T, List<T>> {
SortedTestData(List<T> coll) {
super("SortedTestData", coll,
c -> StreamSupport.stream(Spliterators.spliterator(c.toArray(), Spliterator.ORDERED | Spliterator.SORTED), false),
c -> StreamSupport.stream(Spliterators.spliterator(c.toArray(), Spliterator.ORDERED | Spliterator.SORTED), true),
c -> Spliterators.spliterator(c.toArray(), Spliterator.ORDERED | Spliterator.SORTED),
List::size);
}
}
public static final Comparator<Integer> cNullInteger = (a, b) -> {
if (a == null && b == null) {
return 0;
}
else if (a == null) {
return -1;
}
else if (b == null) {
return 1;
}
else {
return Integer.compare(a, b);
}
};
@Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
public void testDistinctDistinct(String name, TestData.OfRef<Integer> data) {
Collection<Integer> result = exerciseOpsInt(
data,
s -> s.distinct().distinct(),
s -> s.distinct().distinct(),
s -> s.distinct().distinct(),
s -> s.distinct().distinct());
assertUnique(result);
}
@Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
public void testDistinctSorted(String name, TestData.OfRef<Integer> data) {
Collection<Integer> result = withData(data)
.stream(s -> s.distinct().sorted(),
new CollectorOps.TestParallelSizedOp<>())
.exercise();
assertUnique(result);
assertSorted(result);
}
@Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
public void testSortedDistinct(String name, TestData.OfRef<Integer> data) {
Collection<Integer> result = withData(data)
.stream(s -> s.sorted().distinct(),
new CollectorOps.TestParallelSizedOp<>())
.exercise();
assertUnique(result);
assertSorted(result);
}
@Test(groups = { "serialization-hostile" })
public void testStable() {
// Create N instances of Integer all with the same value
List<Integer> input = IntStream.rangeClosed(0, 1000)
.mapToObj(i -> new Integer(1000)) // explicit construction
.collect(Collectors.toList());
Integer expectedElement = input.get(0);
TestData<Integer, Stream<Integer>> data = TestData.Factory.ofCollection(
"1000 instances of Integer with the same value", input);
withData(data)
.stream(Stream::distinct)
.resultAsserter((actual, expected, isOrdered, isParallel) -> {
List<Integer> l = new ArrayList<>();
actual.forEach(l::add);
// Assert stability
// The single result element should be equal in identity to
// the first input element
assertEquals(l.size(), 1);
assertEquals(System.identityHashCode(l.get(0)),
System.identityHashCode(expectedElement));
})
.exercise();
}
}

View file

@ -0,0 +1,136 @@
/*
* Copyright (c) 2013, 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.
*/
package org.openjdk.tests.java.util.stream;
import org.testng.Assert;
import org.testng.annotations.Test;
import java.util.Arrays;
import java.util.Random;
import java.util.Spliterator;
import java.util.stream.DoubleStream;
import java.util.stream.LongStream;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertTrue;
/**
* @test
* @bug 8153293
*/
@Test
public class DoublePrimitiveOpsTests {
// @@@ tests for double are fragile if relying on equality when accumulating and multiplying values
public void testUnBox() {
double sum = Arrays.asList(1.0, 2.0, 3.0, 4.0, 5.0).stream().mapToDouble(i -> i).reduce(0.0, Double::sum);
assertEquals(sum, 1.0 + 2.0 + 3.0 + 4.0 + 5.0);
}
public void testFlags() {
assertTrue(LongStream.range(1, 10).asDoubleStream().boxed().spliterator()
.hasCharacteristics(Spliterator.SORTED));
assertFalse(DoubleStream.of(1, 10).boxed().spliterator()
.hasCharacteristics(Spliterator.SORTED));
}
public void testToArray() {
{
double[] array = LongStream.range(1, 10).asDoubleStream().map(i -> i * 2).toArray();
assertEquals(array, new double[]{2, 4, 6, 8, 10, 12, 14, 16, 18});
}
{
double[] array = LongStream.range(1, 10).parallel().asDoubleStream().map(i -> i * 2).toArray();
assertEquals(array, new double[]{2, 4, 6, 8, 10, 12, 14, 16, 18});
}
}
public void testSort() {
Random r = new Random();
double[] content = DoubleStream.generate(() -> r.nextDouble()).limit(10).toArray();
double[] sortedContent = content.clone();
Arrays.sort(sortedContent);
{
double[] array = Arrays.stream(content).sorted().toArray();
assertEquals(array, sortedContent);
}
{
double[] array = Arrays.stream(content).parallel().sorted().toArray();
assertEquals(array, sortedContent);
}
}
public void testSortDistinct() {
{
double[] range = LongStream.range(0, 10).asDoubleStream().toArray();
assertEquals(LongStream.range(0, 10).asDoubleStream().sorted().distinct().toArray(), range);
assertEquals(LongStream.range(0, 10).asDoubleStream().parallel().sorted().distinct().toArray(), range);
double[] data = {5, 3, 1, 1, 5, Double.NaN, 3, 9, Double.POSITIVE_INFINITY,
Double.NEGATIVE_INFINITY, 2, 9, 1, 0, 8, Double.NaN, -0.0};
double[] expected = {Double.NEGATIVE_INFINITY, -0.0, 0, 1, 2, 3, 5, 8, 9,
Double.POSITIVE_INFINITY, Double.NaN};
assertEquals(DoubleStream.of(data).sorted().distinct().toArray(), expected);
assertEquals(DoubleStream.of(data).parallel().sorted().distinct().toArray(), expected);
}
}
public void testSortSort() {
Random r = new Random();
double[] content = DoubleStream.generate(() -> r.nextDouble()).limit(10).toArray();
double[] sortedContent = content.clone();
Arrays.sort(sortedContent);
{
double[] array = Arrays.stream(content).sorted().sorted().toArray();
assertEquals(array, sortedContent);
}
{
double[] array = Arrays.stream(content).parallel().sorted().sorted().toArray();
assertEquals(array, sortedContent);
}
}
public void testLimit() {
double[] expected = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
{
double[] actual = DoubleStream.iterate(1.0, i -> i + 1.0).limit(9).toArray();
Assert.assertTrue(Arrays.equals(expected, actual));
}
{
double[] actual = LongStream.range(1, 100).parallel().asDoubleStream().limit(9).toArray();
Assert.assertTrue(Arrays.equals(expected, actual));
}
}
}

View file

@ -0,0 +1,109 @@
/*
* Copyright (c) 2012, 2013, 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.
*/
package org.openjdk.tests.java.util.stream;
import java.util.Collection;
import java.util.stream.*;
import org.testng.annotations.Test;
import java.util.Arrays;
import static java.util.stream.LambdaTestHelpers.*;
/**
* FilterOpTest
*
* @author Brian Goetz
*/
@Test
public class FilterOpTest extends OpTestCase {
public void testFilter() {
assertCountSum(countTo(0).stream().filter(pTrue), 0, 0);
assertCountSum(countTo(10).stream().filter(pFalse), 0, 0);
assertCountSum(countTo(10).stream().filter(pEven), 5, 30);
assertCountSum(countTo(10).stream().filter(pOdd), 5, 25);
assertCountSum(countTo(10).stream().filter(pTrue), 10, 55);
assertCountSum(countTo(10).stream().filter(pEven).filter(pOdd), 0, 0);
exerciseOps(countTo(1000), s -> s.filter(pTrue), countTo(1000));
exerciseOps(countTo(1000), s -> s.filter(pFalse), countTo(0));
exerciseOps(countTo(1000), s -> s.filter(e -> e > 100), range(101, 1000));
exerciseOps(countTo(1000), s -> s.filter(e -> e < 100), countTo(99));
exerciseOps(countTo(1000), s -> s.filter(e -> e == 100), Arrays.asList(100));
}
@Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
public void testOps(String name, TestData.OfRef<Integer> data) {
Collection<Integer> result = exerciseOps(data, s -> s.filter(pTrue));
assertEquals(result.size(), data.size());
result = exerciseOps(data, s -> s.filter(pFalse));
assertEquals(result.size(), 0);
exerciseOps(data, s -> s.filter(pEven));
exerciseOps(data, s -> s.filter(pOdd));
result = exerciseOps(data, s -> s.filter(pOdd.and(pEven)));
assertEquals(result.size(), 0);
result = exerciseOps(data, s -> s.filter(pOdd.or(pEven)));
assertEquals(result.size(), data.size());
}
@Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
public void testOps(String name, TestData.OfInt data) {
Collection<Integer> result = exerciseOps(data, s -> s.filter(i -> true));
assertEquals(result.size(), data.size());
result = exerciseOps(data, s -> s.filter(i -> false));
assertEquals(result.size(), 0);
exerciseOps(data, s -> s.filter(i -> 0 == i % 2));
exerciseOps(data, s -> s.filter(i -> 1 == i % 2));
}
@Test(dataProvider = "LongStreamTestData", dataProviderClass = LongStreamTestDataProvider.class)
public void testOps(String name, TestData.OfLong data) {
Collection<Long> result = exerciseOps(data, s -> s.filter(i -> true));
assertEquals(result.size(), data.size());
result = exerciseOps(data, s -> s.filter(i -> false));
assertEquals(result.size(), 0);
exerciseOps(data, s -> s.filter(i -> 0 == i % 2));
exerciseOps(data, s -> s.filter(i -> 1 == i % 2));
}
@Test(dataProvider = "DoubleStreamTestData", dataProviderClass = DoubleStreamTestDataProvider.class)
public void testOps(String name, TestData.OfDouble data) {
Collection<Double> result = exerciseOps(data, s -> s.filter(i -> true));
assertEquals(result.size(), data.size());
result = exerciseOps(data, s -> s.filter(i -> false));
assertEquals(result.size(), 0);
exerciseOps(data, s -> s.filter(i -> 0 == ((long) i) % 2));
exerciseOps(data, s -> s.filter(i -> 1 == ((long) i) % 2));
}
}

View file

@ -0,0 +1,152 @@
/*
* 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
* 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 8148115
*/
package org.openjdk.tests.java.util.stream;
import java.util.*;
import java.util.function.BiConsumer;
import java.util.stream.*;
import org.testng.annotations.Test;
import java.util.function.Function;
import static java.util.stream.LambdaTestHelpers.*;
/**
* FindAnyOpTest
*/
@Test
public class FindAnyOpTest extends OpTestCase {
public void testFindAny() {
assertFalse(Collections.emptySet().stream().findAny().isPresent(), "no result");
assertFalse(countTo(10).stream().filter(x -> x > 10).findAny().isPresent(), "no result");
assertTrue(countTo(10).stream().filter(pEven).findAny().isPresent(), "with result");
}
public void testFindAnyParallel() {
assertFalse(Collections.emptySet().parallelStream().findAny().isPresent(), "no result");
assertFalse(countTo(1000).parallelStream().filter(x -> x > 1000).findAny().isPresent(), "no result");
assertTrue(countTo(1000).parallelStream().filter(pEven).findAny().isPresent(), "with result");
}
@Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
public void testStream(String name, TestData.OfRef<Integer> data) {
exerciseStream(data, s -> s);
exerciseStream(data, s -> s.filter(pTrue));
exerciseStream(data, s -> s.filter(pFalse));
exerciseStream(data, s -> s.filter(pEven));
}
void exerciseStream(TestData.OfRef<Integer> data, Function<Stream<Integer>, Stream<Integer>> fs) {
Optional<Integer> or = withData(data).terminal(fs, s -> s.findAny()).equalator(VALID_ANSWER).exercise();
assertContains(or, fs.apply(data.stream()).iterator());
}
@Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
public void testIntStream(String name, TestData.OfInt data) {
exerciseIntStream(data, s -> s);
exerciseIntStream(data, s -> s.filter(ipTrue));
exerciseIntStream(data, s -> s.filter(ipFalse));
exerciseIntStream(data, s -> s.filter(ipEven));
}
void exerciseIntStream(TestData.OfInt data, Function<IntStream, IntStream> fs) {
OptionalInt or = withData(data).terminal(fs, s -> s.findAny()).equalator(INT_VALID_ANSWER).exercise();
if (or.isPresent()) {
int r = or.getAsInt();
PrimitiveIterator.OfInt it = fs.apply(data.stream()).iterator();
boolean contained = false;
while (!contained && it.hasNext()) {
contained = r == it.nextInt();
}
assertTrue(contained);
}
else {
assertFalse(fs.apply(data.stream()).iterator().hasNext());
}
}
@Test(dataProvider = "LongStreamTestData", dataProviderClass = LongStreamTestDataProvider.class)
public void testLongStream(String name, TestData.OfLong data) {
exerciseLongStream(data, s -> s);
exerciseLongStream(data, s -> s.filter(lpTrue));
exerciseLongStream(data, s -> s.filter(lpFalse));
exerciseLongStream(data, s -> s.filter(lpEven));
}
void exerciseLongStream(TestData.OfLong data, Function<LongStream, LongStream> fs) {
OptionalLong or = withData(data).terminal(fs, s -> s.findAny()).equalator(LONG_VALID_ANSWER).exercise();
if (or.isPresent()) {
long r = or.getAsLong();
PrimitiveIterator.OfLong it = fs.apply(data.stream()).iterator();
boolean contained = false;
while (!contained && it.hasNext()) {
contained = r == it.nextLong();
}
assertTrue(contained);
}
else {
assertFalse(fs.apply(data.stream()).iterator().hasNext());
}
}
@Test(dataProvider = "DoubleStreamTestData", dataProviderClass = DoubleStreamTestDataProvider.class)
public void testDoubleStream(String name, TestData.OfDouble data) {
exerciseDoubleStream(data, s -> s);
exerciseDoubleStream(data, s -> s.filter(dpTrue));
exerciseDoubleStream(data, s -> s.filter(dpEven));
exerciseDoubleStream(data, s -> s.filter(dpFalse));
}
void exerciseDoubleStream(TestData.OfDouble data, Function<DoubleStream, DoubleStream> fs) {
OptionalDouble or = withData(data).terminal(fs, s -> s.findAny()).equalator(DOUBLE_VALID_ANSWER).exercise();
if (or.isPresent()) {
double r = or.getAsDouble();
PrimitiveIterator.OfDouble it = fs.apply(data.stream()).iterator();
boolean contained = false;
while (!contained && it.hasNext()) {
contained = r == it.nextDouble();
}
assertTrue(contained);
}
else {
assertFalse(fs.apply(data.stream()).iterator().hasNext());
}
}
static final BiConsumer<Optional<Integer>, Optional<Integer>> VALID_ANSWER = (a, b) -> assertEquals(a.isPresent(), b.isPresent());
static final BiConsumer<OptionalInt, OptionalInt> INT_VALID_ANSWER = (a, b) -> assertEquals(a.isPresent(), b.isPresent());
static final BiConsumer<OptionalLong, OptionalLong> LONG_VALID_ANSWER = (a, b) -> assertEquals(a.isPresent(), b.isPresent());
static final BiConsumer<OptionalDouble, OptionalDouble> DOUBLE_VALID_ANSWER = (a, b) -> assertEquals(a.isPresent(), b.isPresent());
}

View file

@ -0,0 +1,142 @@
/*
* 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
* 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 8148115
*/
package org.openjdk.tests.java.util.stream;
import java.util.*;
import java.util.stream.*;
import org.testng.annotations.Test;
import java.util.function.Function;
import static java.util.stream.LambdaTestHelpers.*;
/**
* FindFirstOpTest
*/
@Test
public class FindFirstOpTest extends OpTestCase {
public void testFindFirst() {
assertFalse(Collections.emptySet().stream().findFirst().isPresent(), "no result");
assertFalse(countTo(10).stream().filter(x -> x > 10).findFirst().isPresent(), "no result");
exerciseOps(countTo(1000), s -> Arrays.asList(new Integer[]{s.filter(pEven).findFirst().get()}).stream(), Arrays.asList(2));
exerciseOps(countTo(1000), s -> Arrays.asList(new Integer[]{s.findFirst().get()}).stream(), Arrays.asList(1));
exerciseOps(countTo(1000), s -> Arrays.asList(new Integer[]{s.filter(e -> e == 499).findFirst().get()}).stream(), Arrays.asList(499));
exerciseOps(countTo(1000), s -> Arrays.asList(new Integer[]{s.filter(e -> e == 999).findFirst().get()}).stream(), Arrays.asList(999));
exerciseOps(countTo(0), s -> Arrays.asList(new Integer[]{s.findFirst().orElse(-1)}).stream(), Arrays.asList(-1));
exerciseOps(countTo(1000), s -> Arrays.asList(new Integer[]{s.filter(e -> e == 1499).findFirst().orElse(-1)}).stream(), Arrays.asList(-1));
}
@Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
public void testStream(String name, TestData.OfRef<Integer> data) {
exerciseStream(data, s -> s);
exerciseStream(data, s -> s.filter(pTrue));
exerciseStream(data, s -> s.filter(pFalse));
exerciseStream(data, s -> s.filter(pEven));
}
void exerciseStream(TestData.OfRef<Integer> data, Function<Stream<Integer>, Stream<Integer>> fs) {
Iterator<Integer> i = fs.apply(data.stream()).iterator();
Optional<Integer> expected = i.hasNext() ? Optional.of(i.next()) : Optional.empty();
withData(data).terminal(fs, s -> s.findFirst())
.expectedResult(expected)
.resultAsserter((act, exp, ord, par) -> {
if (par & !ord) {
assertContains(act, fs.apply(data.stream()).iterator());
}
else {
assertEquals(act, exp);
}
})
.exercise();
}
@Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
public void testIntStream(String name, TestData.OfInt data) {
exerciseIntStream(data, s -> s);
exerciseIntStream(data, s -> s.filter(ipTrue));
exerciseIntStream(data, s -> s.filter(ipFalse));
exerciseIntStream(data, s -> s.filter(ipEven));
}
void exerciseIntStream(TestData.OfInt data, Function<IntStream, IntStream> fs) {
OptionalInt r = exerciseTerminalOps(data, fs, s -> s.findFirst());
if (r.isPresent()) {
PrimitiveIterator.OfInt i = fs.apply(data.stream()).iterator();
assertTrue(i.hasNext());
assertEquals(i.nextInt(), r.getAsInt());
}
else {
assertFalse(fs.apply(data.stream()).iterator().hasNext());
}
}
@Test(dataProvider = "LongStreamTestData", dataProviderClass = LongStreamTestDataProvider.class)
public void testLongStream(String name, TestData.OfLong data) {
exerciseLongStream(data, s -> s);
exerciseLongStream(data, s -> s.filter(lpTrue));
exerciseLongStream(data, s -> s.filter(lpFalse));
exerciseLongStream(data, s -> s.filter(lpEven));
}
void exerciseLongStream(TestData.OfLong data, Function<LongStream, LongStream> fs) {
OptionalLong r = exerciseTerminalOps(data, fs, s -> s.findFirst());
if (r.isPresent()) {
PrimitiveIterator.OfLong i = fs.apply(data.stream()).iterator();
assertTrue(i.hasNext());
assertEquals(i.nextLong(), r.getAsLong());
}
else {
assertFalse(fs.apply(data.stream()).iterator().hasNext());
}
}
@Test(dataProvider = "DoubleStreamTestData", dataProviderClass = DoubleStreamTestDataProvider.class)
public void testDoubleStream(String name, TestData.OfDouble data) {
exerciseDoubleStream(data, s -> s);
exerciseDoubleStream(data, s -> s.filter(dpTrue));
exerciseDoubleStream(data, s -> s.filter(dpFalse));
exerciseDoubleStream(data, s -> s.filter(dpEven));
}
void exerciseDoubleStream(TestData.OfDouble data, Function<DoubleStream, DoubleStream> fs) {
OptionalDouble r = exerciseTerminalOps(data, fs, s -> s.findFirst());
if (r.isPresent()) {
PrimitiveIterator.OfDouble i = fs.apply(data.stream()).iterator();
assertTrue(i.hasNext());
assertEquals(i.nextDouble(), r.getAsDouble());
}
else {
assertFalse(fs.apply(data.stream()).iterator().hasNext());
}
}
}

View file

@ -0,0 +1,303 @@
/*
* Copyright (c) 2012, 2024, 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
* @summary flat-map operations
* @bug 8044047 8076458 8075939 8196106
*/
package org.openjdk.tests.java.util.stream;
import org.testng.annotations.Test;
import java.util.Arrays;
import java.util.Collection;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.DoubleStream;
import java.util.stream.DoubleStreamTestDataProvider;
import java.util.stream.IntStream;
import java.util.stream.IntStreamTestDataProvider;
import java.util.stream.LongStream;
import java.util.stream.LongStreamTestDataProvider;
import java.util.stream.OpTestCase;
import java.util.stream.Stream;
import java.util.stream.StreamTestDataProvider;
import java.util.stream.TestData;
import static java.util.stream.LambdaTestHelpers.*;
import static java.util.stream.ThrowableHelper.checkNPE;
@Test
public class FlatMapOpTest extends OpTestCase {
@Test
public void testNullMapper() {
checkNPE(() -> Stream.of(1).flatMap(null));
checkNPE(() -> IntStream.of(1).flatMap(null));
checkNPE(() -> LongStream.of(1).flatMap(null));
checkNPE(() -> DoubleStream.of(1).flatMap(null));
}
static final Function<Integer, Stream<Integer>> integerRangeMapper
= e -> IntStream.range(0, e).boxed();
@Test
public void testFlatMap() {
String[] stringsArray = {"hello", "there", "", "yada"};
Stream<String> strings = Arrays.asList(stringsArray).stream();
assertConcat(strings.flatMap(flattenChars).iterator(), "hellothereyada");
assertCountSum(countTo(10).stream().flatMap(mfId), 10, 55);
assertCountSum(countTo(10).stream().flatMap(mfNull), 0, 0);
assertCountSum(countTo(3).stream().flatMap(mfLt), 6, 4);
assertCountSum(countTo(10).stream().flatMap(e -> Stream.empty()), 0, 0);
exerciseOps(TestData.Factory.ofArray("stringsArray", stringsArray), s -> s.flatMap(flattenChars));
exerciseOps(TestData.Factory.ofArray("LONG_STRING", new String[] {LONG_STRING}), s -> s.flatMap(flattenChars));
}
@Test
public void testClose() {
AtomicInteger before = new AtomicInteger();
AtomicInteger onClose = new AtomicInteger();
Supplier<Stream<Integer>> s = () -> {
before.set(0); onClose.set(0);
return Stream.of(1, 2).peek(e -> before.getAndIncrement());
};
s.get().flatMap(i -> Stream.of(i, i).onClose(onClose::getAndIncrement)).count();
assertEquals(before.get(), onClose.get());
s.get().flatMapToInt(i -> IntStream.of(i, i).onClose(onClose::getAndIncrement)).count();
assertEquals(before.get(), onClose.get());
s.get().flatMapToLong(i -> LongStream.of(i, i).onClose(onClose::getAndIncrement)).count();
assertEquals(before.get(), onClose.get());
s.get().flatMapToDouble(i -> DoubleStream.of(i, i).onClose(onClose::getAndIncrement)).count();
assertEquals(before.get(), onClose.get());
}
@Test
public void testIntClose() {
AtomicInteger before = new AtomicInteger();
AtomicInteger onClose = new AtomicInteger();
IntStream.of(1, 2).peek(e -> before.getAndIncrement()).
flatMap(i -> IntStream.of(i, i).onClose(onClose::getAndIncrement)).count();
assertEquals(before.get(), onClose.get());
}
@Test
public void testLongClose() {
AtomicInteger before = new AtomicInteger();
AtomicInteger onClose = new AtomicInteger();
LongStream.of(1, 2).peek(e -> before.getAndIncrement()).
flatMap(i -> LongStream.of(i, i).onClose(onClose::getAndIncrement)).count();
assertEquals(before.get(), onClose.get());
}
@Test
public void testDoubleClose() {
AtomicInteger before = new AtomicInteger();
AtomicInteger onClose = new AtomicInteger();
DoubleStream.of(1, 2).peek(e -> before.getAndIncrement()).
flatMap(i -> DoubleStream.of(i, i).onClose(onClose::getAndIncrement)).count();
assertEquals(before.get(), onClose.get());
}
@Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
public void testOps(String name, TestData.OfRef<Integer> data) {
Collection<Integer> result = exerciseOps(data, s -> s.flatMap(mfId));
assertEquals(data.size(), result.size());
result = exerciseOps(data, s -> s.flatMap(mfNull));
assertEquals(0, result.size());
result = exerciseOps(data, s-> s.flatMap(e -> Stream.empty()));
assertEquals(0, result.size());
}
@Test(dataProvider = "StreamTestData<Integer>.small", dataProviderClass = StreamTestDataProvider.class)
public void testOpsX(String name, TestData.OfRef<Integer> data) {
exerciseOps(data, s -> s.flatMap(mfLt));
exerciseOps(data, s -> s.flatMap(integerRangeMapper));
exerciseOps(data, s -> s.flatMap((Integer e) -> IntStream.range(0, e).boxed().limit(10)));
}
@Test
public void testOpsShortCircuit() {
AtomicInteger count = new AtomicInteger();
Stream.of(0).flatMap(i -> IntStream.range(0, 100).boxed()).
peek(i -> count.incrementAndGet()).
limit(10).toArray();
assertEquals(count.get(), 10);
}
//
@Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
public void testIntOps(String name, TestData.OfInt data) {
Collection<Integer> result = exerciseOps(data, s -> s.flatMap(IntStream::of));
assertEquals(data.size(), result.size());
assertContents(data, result);
result = exerciseOps(data, s -> s.boxed().flatMapToInt(IntStream::of));
assertEquals(data.size(), result.size());
assertContents(data, result);
result = exerciseOps(data, s -> s.flatMap(i -> IntStream.empty()));
assertEquals(0, result.size());
}
@Test(dataProvider = "IntStreamTestData.small", dataProviderClass = IntStreamTestDataProvider.class)
public void testIntOpsX(String name, TestData.OfInt data) {
exerciseOps(data, s -> s.flatMap(e -> IntStream.range(0, e)));
exerciseOps(data, s -> s.flatMap(e -> IntStream.range(0, e).limit(10)));
exerciseOps(data, s -> s.boxed().flatMapToInt(e -> IntStream.range(0, e)));
exerciseOps(data, s -> s.boxed().flatMapToInt(e -> IntStream.range(0, e).limit(10)));
}
@Test
public void testIntOpsShortCircuit() {
AtomicInteger count = new AtomicInteger();
IntStream.of(0).flatMap(i -> IntStream.range(0, 100)).
peek(i -> count.incrementAndGet()).
limit(10).toArray();
assertEquals(count.get(), 10);
count.set(0);
Stream.of(0).flatMapToInt(i -> IntStream.range(0, 100)).
peek(i -> count.incrementAndGet()).
limit(10).toArray();
assertEquals(count.get(), 10);
}
//
@Test(dataProvider = "LongStreamTestData", dataProviderClass = LongStreamTestDataProvider.class)
public void testLongOps(String name, TestData.OfLong data) {
Collection<Long> result = exerciseOps(data, s -> s.flatMap(LongStream::of));
assertEquals(data.size(), result.size());
assertContents(data, result);
result = exerciseOps(data, s -> s.boxed().flatMapToLong(LongStream::of));
assertEquals(data.size(), result.size());
assertContents(data, result);
result = exerciseOps(data, s -> LongStream.empty());
assertEquals(0, result.size());
}
@Test(dataProvider = "LongStreamTestData.small", dataProviderClass = LongStreamTestDataProvider.class)
public void testLongOpsX(String name, TestData.OfLong data) {
exerciseOps(data, s -> s.flatMap(e -> LongStream.range(0, e)));
exerciseOps(data, s -> s.flatMap(e -> LongStream.range(0, e).limit(10)));
}
@Test
public void testLongOpsShortCircuit() {
AtomicInteger count = new AtomicInteger();
LongStream.of(0).flatMap(i -> LongStream.range(0, 100)).
peek(i -> count.incrementAndGet()).
limit(10).toArray();
assertEquals(count.get(), 10);
count.set(0);
Stream.of(0).flatMapToLong(i -> LongStream.range(0, 100)).
peek(i -> count.incrementAndGet()).
limit(10).toArray();
assertEquals(count.get(), 10);
}
//
@Test(dataProvider = "DoubleStreamTestData", dataProviderClass = DoubleStreamTestDataProvider.class)
public void testDoubleOps(String name, TestData.OfDouble data) {
Collection<Double> result = exerciseOps(data, s -> s.flatMap(DoubleStream::of));
assertEquals(data.size(), result.size());
assertContents(data, result);
result = exerciseOps(data, s -> s.boxed().flatMapToDouble(DoubleStream::of));
assertEquals(data.size(), result.size());
assertContents(data, result);
result = exerciseOps(data, s -> DoubleStream.empty());
assertEquals(0, result.size());
}
@Test(dataProvider = "DoubleStreamTestData.small", dataProviderClass = DoubleStreamTestDataProvider.class)
public void testDoubleOpsX(String name, TestData.OfDouble data) {
exerciseOps(data, s -> s.flatMap(e -> IntStream.range(0, (int) e).asDoubleStream()));
exerciseOps(data, s -> s.flatMap(e -> IntStream.range(0, (int) e).limit(10).asDoubleStream()));
}
@Test
public void testDoubleOpsShortCircuit() {
AtomicInteger count = new AtomicInteger();
DoubleStream.of(0).flatMap(i -> IntStream.range(0, 100).asDoubleStream()).
peek(i -> count.incrementAndGet()).
limit(10).toArray();
assertEquals(count.get(), 10);
count.set(0);
Stream.of(0).flatMapToDouble(i -> IntStream.range(0, 100).asDoubleStream()).
peek(i -> count.incrementAndGet()).
limit(10).toArray();
assertEquals(count.get(), 10);
}
@Test
public void testTerminationOfNestedInfiniteStreams() {
var refExpected = Stream.generate(() -> "").limit(5).toList();
var refResult = Stream.generate(() -> "")
.flatMap(c -> Stream.generate(() -> c).flatMap(x -> Stream.generate(() -> x)))
.limit(5).toList();
assertEquals(refResult, refExpected);
var intExpected = IntStream.generate(() -> 1).limit(5).sum();
var intResult = IntStream.generate(() -> 1)
.flatMap(c -> IntStream.generate(() -> c).flatMap(x -> IntStream.generate(() -> x)))
.limit(5).sum();
assertEquals(intResult, intExpected);
var longExpected = LongStream.generate(() -> 1L).limit(5).sum();
var longResult = LongStream.generate(() -> 1L)
.flatMap(c -> LongStream.generate(() -> c).flatMap(x -> LongStream.generate(() -> x)))
.limit(5).sum();
assertEquals(longResult, longExpected);
var doubleExpected = DoubleStream.generate(() -> 0d).limit(5).sum();
var doubleResult = DoubleStream.generate(() -> 0d)
.flatMap(c -> DoubleStream.generate(() -> c).flatMap(x -> DoubleStream.generate(() -> x)))
.limit(5).sum();
assertEquals(doubleResult, doubleExpected);
}
}

View file

@ -0,0 +1,261 @@
/*
* Copyright (c) 2012, 2013, 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.
*/
package org.openjdk.tests.java.util.stream;
import org.testng.annotations.Test;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Function;
import java.util.stream.*;
import static java.util.stream.LambdaTestHelpers.countTo;
/**
* ForEachOpTest
*/
@Test
public class ForEachOpTest extends OpTestCase {
@Test(groups = { "serialization-hostile" })
public void testForEach() {
exerciseTerminalOps(countTo(10),
s -> {
AtomicInteger count = new AtomicInteger(0);
s.forEach(e -> count.incrementAndGet());
return count.get();
},
10);
exerciseTerminalOps(countTo(10),
s -> {
AtomicInteger sum = new AtomicInteger(0);
s.forEach(sum::addAndGet);
return sum.get();
},
55);
}
private <U> ResultAsserter<List<U>> resultAsserter() {
return (act, exp, ord, par) -> {
if (par) {
LambdaTestHelpers.assertContentsUnordered(act, exp);
}
else {
LambdaTestHelpers.assertContents(act, exp);
}
};
}
@Test(groups = { "serialization-hostile" })
public void testForEachOrdered() {
List<Integer> input = countTo(10000);
TestData.OfRef<Integer> data = TestData.Factory.ofCollection("[1, 10000]", input);
Function<Stream<Integer>, List<Integer>> terminalFunc = s -> {
List<Integer> l = new ArrayList<>();
s.forEachOrdered(l::add);
return l;
};
// Test head
withData(data).
terminal(terminalFunc).
expectedResult(input).
exercise();
// Test multiple stages
withData(data).
terminal(s -> s.map(LambdaTestHelpers.identity()), terminalFunc).
expectedResult(input).
exercise();
}
@Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
public void testForEach(String name, TestData.OfRef<Integer> data) {
Function<Stream<Integer>, List<Integer>> terminalFunc = s -> {
List<Integer> l = Collections.synchronizedList(new ArrayList<>());
s.forEach(l::add);
return l;
};
// Test head
withData(data).
terminal(terminalFunc).
resultAsserter(resultAsserter()).
exercise();
// Test multiple stages
withData(data).
terminal(s -> s.map(LambdaTestHelpers.identity()), terminalFunc).
resultAsserter(resultAsserter()).
exercise();
}
//
@Test(groups = { "serialization-hostile" })
public void testIntForEachOrdered() {
List<Integer> input = countTo(10000);
TestData.OfInt data = TestData.Factory.ofIntSupplier("[1, 10000]",
() -> IntStream.range(1, 10001));
Function<IntStream, List<Integer>> terminalFunc = s -> {
List<Integer> l = new ArrayList<>();
s.forEachOrdered(l::add);
return l;
};
// Test head
withData(data).
terminal(terminalFunc).
expectedResult(input).
exercise();
// Test multiple stages
withData(data).
terminal(s -> s.map(i -> i), terminalFunc).
expectedResult(input).
exercise();
}
@Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
public void testIntForEach(String name, TestData.OfInt data) {
Function<IntStream, List<Integer>> terminalFunc = s -> {
List<Integer> l = Collections.synchronizedList(new ArrayList<Integer>());
s.forEach(l::add);
return l;
};
// Test head
withData(data).
terminal(terminalFunc).
resultAsserter(resultAsserter()).
exercise();
// Test multiple stages
withData(data).
terminal(s -> s.map(i -> i), terminalFunc).
resultAsserter(resultAsserter()).
exercise();
}
//
@Test(groups = { "serialization-hostile" })
public void testLongForEachOrdered() {
List<Integer> input = countTo(10000);
TestData.OfLong data = TestData.Factory.ofLongSupplier("[1, 10000]",
() -> LongStream.range(1, 10001));
Function<LongStream, List<Integer>> terminalFunc = s -> {
List<Integer> l = new ArrayList<>();
s.forEachOrdered(e -> l.add((int) e));
return l;
};
// Test head
withData(data).
terminal(terminalFunc).
expectedResult(input).
exercise();
// Test multiple stages
withData(data).
terminal(s -> s.map(i -> i), terminalFunc).
expectedResult(input).
exercise();
}
@Test(dataProvider = "LongStreamTestData", dataProviderClass = LongStreamTestDataProvider.class)
public void testLongOps(String name, TestData.OfLong data) {
Function<LongStream, List<Long>> terminalFunc = s -> {
List<Long> l = Collections.synchronizedList(new ArrayList<Long>());
s.forEach(l::add);
return l;
};
// Test head
withData(data).
terminal(terminalFunc).
resultAsserter(resultAsserter()).
exercise();
// Test multiple stages
withData(data).
terminal(s -> s.map(i -> i), terminalFunc).
resultAsserter(resultAsserter()).
exercise();
}
//
@Test(groups = { "serialization-hostile" })
public void testDoubleForEachOrdered() {
List<Integer> input = countTo(10000);
TestData.OfDouble data = TestData.Factory.ofDoubleSupplier("[1, 10000]",
() -> IntStream.range(1, 10001).asDoubleStream());
Function<DoubleStream, List<Integer>> terminalFunc = s -> {
List<Integer> l = new ArrayList<>();
s.forEachOrdered(e -> l.add((int) e));
return l;
};
// Test head
withData(data).
terminal(terminalFunc).
expectedResult(input).
exercise();
// Test multiple stages
withData(data).
terminal(s -> s.map(i -> i), terminalFunc).
expectedResult(input).
exercise();
}
@Test(dataProvider = "DoubleStreamTestData", dataProviderClass = DoubleStreamTestDataProvider.class)
public void testDoubleOps(String name, TestData.OfDouble data) {
Function<DoubleStream, List<Double>> terminalFunc = s -> {
List<Double> l = Collections.synchronizedList(new ArrayList<Double>());
s.forEach(l::add);
return l;
};
// Test head
withData(data).
terminal(terminalFunc).
resultAsserter(resultAsserter()).
exercise();
// Test multiple stages
withData(data).
terminal(s -> s.map(i -> i), terminalFunc).
resultAsserter(resultAsserter()).
exercise();
}
}

View file

@ -0,0 +1,173 @@
/*
* Copyright (c) 2012, 2013, 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.
*/
package org.openjdk.tests.java.util.stream;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collector;
import java.util.stream.Collectors;
import java.util.stream.LambdaTestHelpers;
import java.util.stream.OpTestCase;
import java.util.stream.Stream;
import java.util.stream.StreamTestDataProvider;
import java.util.stream.TestData;
import org.testng.annotations.Test;
import static java.util.stream.LambdaTestHelpers.countTo;
import static java.util.stream.LambdaTestHelpers.mDoubler;
import static java.util.stream.LambdaTestHelpers.mId;
import static java.util.stream.LambdaTestHelpers.mZero;
import static java.util.stream.LambdaTestHelpers.pEven;
import static java.util.stream.LambdaTestHelpers.pFalse;
import static java.util.stream.LambdaTestHelpers.pOdd;
import static java.util.stream.LambdaTestHelpers.pTrue;
/**
* GroupByOpTest
*
*/
@Test
public class GroupByOpTest extends OpTestCase {
public void testBypassCollect() {
@SuppressWarnings("unchecked")
Collector<Integer, Map<Boolean, List<Integer>>, Map<Boolean, List<Integer>>> collector
= (Collector<Integer, Map<Boolean, List<Integer>>, Map<Boolean, List<Integer>>>) Collectors.groupingBy(LambdaTestHelpers.forPredicate(pEven, true, false));
Map<Boolean, List<Integer>> m = collector.supplier().get();
int[] ints = countTo(10).stream().mapToInt(e -> (int) e).toArray();
for (int i : ints)
collector.accumulator().accept(m, i);
assertEquals(2, m.keySet().size());
for(Collection<Integer> group : m.values()) {
int count = 0;
Stream<Integer> stream = group.stream();
Iterator<Integer> it = stream.iterator();
while (it.hasNext()) {
it.next();
++count;
}
assertEquals(5, count);
}
}
public void testGroupBy() {
Map<Boolean,List<Integer>> result = countTo(10).stream().collect(Collectors.groupingBy(LambdaTestHelpers.forPredicate(pEven, true, false)));
assertEquals(2, result.keySet().size());
for(Collection<Integer> group : result.values()) {
int count = 0;
Stream<Integer> stream = group.stream();
Iterator<Integer> it = stream.iterator();
while (it.hasNext()) {
it.next();
++count;
}
assertEquals(5, count);
}
}
static class MapperData<T, K> {
Function<T, K> m;
int expectedSize;
MapperData(Function<T, K> m, int expectedSize) {
this.m = m;
this.expectedSize = expectedSize;
}
}
List<MapperData<Integer, ?>> getMapperData(TestData.OfRef<Integer> data) {
int uniqueSize = data.into(new HashSet<>()).size();
return Arrays.asList(
new MapperData<>(mId, uniqueSize),
new MapperData<>(mZero, Math.min(1, data.size())),
new MapperData<>(mDoubler, uniqueSize),
new MapperData<>(LambdaTestHelpers.compose(mId, mDoubler), uniqueSize),
new MapperData<>(LambdaTestHelpers.compose(mDoubler, mDoubler), uniqueSize),
new MapperData<>(LambdaTestHelpers.forPredicate(pFalse, true, false), Math.min(1, uniqueSize)),
new MapperData<>(LambdaTestHelpers.forPredicate(pTrue, true, false), Math.min(1, uniqueSize)),
new MapperData<>(LambdaTestHelpers.forPredicate(pEven, true, false), Math.min(2, uniqueSize)),
new MapperData<>(LambdaTestHelpers.forPredicate(pOdd, true, false), Math.min(2, uniqueSize))
);
}
@Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
public void testOps(String name, TestData.OfRef<Integer> data) {
// @@@ More things to test here:
// - Every value in data is present in right bucket
// - Total number of values equals size of data
for (MapperData<Integer, ?> md : getMapperData(data)) {
Collector<Integer, ?, Map<Object, List<Integer>>> tab = Collectors.groupingBy(md.m);
Map<Object, List<Integer>> result =
withData(data)
.terminal(s -> s, s -> s.collect(tab))
.resultAsserter((act, exp, ord, par) -> {
if (par & !ord) {
GroupByOpTest.assertMultiMapEquals(act, exp);
}
else {
GroupByOpTest.assertObjectEquals(act, exp);
}
})
.exercise();
assertEquals(result.keySet().size(), md.expectedSize);
}
}
static void assertObjectEquals(Object a, Object b) {
assertTrue(Objects.equals(a, b));
}
static <K, V> void assertMultiMapEquals(Map<K, ? extends Collection<V>> a, Map<K, ? extends Collection<V>> b) {
assertTrue(multiMapEquals(a, b));
}
static<K, V> boolean multiMapEquals(Map<K, ? extends Collection<V>> a, Map<K, ? extends Collection<V>> b) {
if (!Objects.equals(a.keySet(), b.keySet())) {
return false;
}
for (K k : a.keySet()) {
Set<V> as = new HashSet<>(a.get(k));
Set<V> bs = new HashSet<>(b.get(k));
if (!Objects.equals(as, bs)) {
return false;
}
}
return true;
}
}

View file

@ -0,0 +1,453 @@
/*
* Copyright (c) 2012, 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
* 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.
*/
package org.openjdk.tests.java.util.stream;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.List;
import java.util.Spliterator;
import java.util.function.Function;
import java.util.function.UnaryOperator;
import java.util.stream.DoubleStream;
import java.util.stream.DoubleStreamTestScenario;
import java.util.stream.IntStream;
import java.util.stream.IntStreamTestScenario;
import java.util.stream.LambdaTestHelpers;
import java.util.stream.LongStream;
import java.util.stream.LongStreamTestScenario;
import java.util.stream.OpTestCase;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
import java.util.stream.StreamTestScenario;
import java.util.stream.TestData;
import static java.util.stream.LambdaTestHelpers.assertUnique;
@Test
public class InfiniteStreamWithLimitOpTest extends OpTestCase {
private static final long SKIP_LIMIT_SIZE = 1 << 16;
@DataProvider(name = "Stream.limit")
@SuppressWarnings("rawtypes")
public static Object[][] sliceFunctionsDataProvider() {
Function<String, String> f = s -> String.format(s, SKIP_LIMIT_SIZE);
List<Object[]> data = new ArrayList<>();
data.add(new Object[]{f.apply("Stream.limit(%d)"),
(UnaryOperator<Stream>) s -> s.limit(SKIP_LIMIT_SIZE)});
data.add(new Object[]{f.apply("Stream.skip(%1$d).limit(%1$d)"),
(UnaryOperator<Stream>) s -> s.skip(SKIP_LIMIT_SIZE).limit(SKIP_LIMIT_SIZE)});
return data.toArray(new Object[0][]);
}
@DataProvider(name = "IntStream.limit")
public static Object[][] intSliceFunctionsDataProvider() {
Function<String, String> f = s -> String.format(s, SKIP_LIMIT_SIZE);
List<Object[]> data = new ArrayList<>();
data.add(new Object[]{f.apply("IntStream.limit(%d)"),
(UnaryOperator<IntStream>) s -> s.limit(SKIP_LIMIT_SIZE)});
data.add(new Object[]{f.apply("IntStream.skip(%1$d).limit(%1$d)"),
(UnaryOperator<IntStream>) s -> s.skip(SKIP_LIMIT_SIZE).limit(SKIP_LIMIT_SIZE)});
return data.toArray(new Object[0][]);
}
@DataProvider(name = "LongStream.limit")
public static Object[][] longSliceFunctionsDataProvider() {
Function<String, String> f = s -> String.format(s, SKIP_LIMIT_SIZE);
List<Object[]> data = new ArrayList<>();
data.add(new Object[]{f.apply("LongStream.limit(%d)"),
(UnaryOperator<LongStream>) s -> s.limit(SKIP_LIMIT_SIZE)});
data.add(new Object[]{f.apply("LongStream.skip(%1$d).limit(%1$d)"),
(UnaryOperator<LongStream>) s -> s.skip(SKIP_LIMIT_SIZE).limit(SKIP_LIMIT_SIZE)});
return data.toArray(new Object[0][]);
}
@DataProvider(name = "DoubleStream.limit")
public static Object[][] doubleSliceFunctionsDataProvider() {
Function<String, String> f = s -> String.format(s, SKIP_LIMIT_SIZE);
List<Object[]> data = new ArrayList<>();
data.add(new Object[]{f.apply("DoubleStream.limit(%d)"),
(UnaryOperator<DoubleStream>) s -> s.limit(SKIP_LIMIT_SIZE)});
data.add(new Object[]{f.apply("DoubleStream.skip(%1$d).limit(%1$d)"),
(UnaryOperator<DoubleStream>) s -> s.skip(SKIP_LIMIT_SIZE).limit(SKIP_LIMIT_SIZE)});
return data.toArray(new Object[0][]);
}
private <T> ResultAsserter<Iterable<T>> unorderedAsserter() {
return (act, exp, ord, par) -> {
if (par & !ord) {
// Can only assert that all elements of the actual result
// are distinct and that the count is the limit size
// any element within the range [0, Long.MAX_VALUE) may be
// present
assertUnique(act);
long count = 0;
for (T l : act) {
count++;
}
assertEquals(count, SKIP_LIMIT_SIZE, "size not equal");
}
else {
LambdaTestHelpers.assertContents(act, exp);
}
};
}
private TestData.OfRef<Long> refLongs() {
return refLongRange(0, Long.MAX_VALUE);
}
private TestData.OfRef<Long> refLongRange(long l, long u) {
return TestData.Factory.ofSupplier(
String.format("[%d, %d)", l, u),
() -> LongStream.range(l, u).boxed());
}
private TestData.OfInt ints() {
return intRange(0, Integer.MAX_VALUE);
}
private TestData.OfInt intRange(int l, int u) {
return TestData.Factory.ofIntSupplier(
String.format("[%d, %d)", l, u),
() -> IntStream.range(l, u));
}
private TestData.OfLong longs() {
return longRange(0, Long.MAX_VALUE);
}
private TestData.OfLong longRange(long l, long u) {
return TestData.Factory.ofLongSupplier(
String.format("[%d, %d)", l, u),
() -> LongStream.range(l, u));
}
private TestData.OfDouble doubles() {
return doubleRange(0, 1L << 53);
}
private TestData.OfDouble doubleRange(long l, long u) {
return TestData.Factory.ofDoubleSupplier(
String.format("[%d, %d)", l, u),
() -> LongStream.range(l, u).mapToDouble(i -> (double) i));
}
// Sized/subsized range
@Test(dataProvider = "Stream.limit")
public void testSubsizedWithRange(String description, UnaryOperator<Stream<Long>> fs) {
// Range is [0, Long.MAX_VALUE), splits are SUBSIZED
// Such a size will induce out of memory errors for incorrect
// slice implementations
withData(refLongs()).
stream(s -> fs.apply(s)).
without(StreamTestScenario.CLEAR_SIZED_SCENARIOS).
exercise();
}
@Test(dataProvider = "IntStream.limit")
public void testIntSubsizedWithRange(String description, UnaryOperator<IntStream> fs) {
// Range is [0, Integer.MAX_VALUE), splits are SUBSIZED
// Such a size will induce out of memory errors for incorrect
// slice implementations
withData(ints()).
stream(s -> fs.apply(s)).
without(IntStreamTestScenario.CLEAR_SIZED_SCENARIOS).
exercise();
}
@Test(dataProvider = "LongStream.limit")
public void testLongSubsizedWithRange(String description, UnaryOperator<LongStream> fs) {
// Range is [0, Long.MAX_VALUE), splits are SUBSIZED
// Such a size will induce out of memory errors for incorrect
// slice implementations
withData(longs()).
stream(s -> fs.apply(s)).
without(LongStreamTestScenario.CLEAR_SIZED_SCENARIOS).
exercise();
}
@Test(dataProvider = "DoubleStream.limit")
public void testDoubleSubsizedWithRange(String description, UnaryOperator<DoubleStream> fs) {
// Range is [0, 2^53), splits are SUBSIZED
// Such a size will induce out of memory errors for incorrect
// slice implementations
withData(doubles()).
stream(s -> fs.apply(s)).
without(DoubleStreamTestScenario.CLEAR_SIZED_SCENARIOS).
exercise();
}
// Unordered finite not SIZED/SUBSIZED
@Test(dataProvider = "Stream.limit")
public void testUnorderedFinite(String description, UnaryOperator<Stream<Long>> fs) {
// Range is [0, Long.MAX_VALUE), splits are SUBSIZED
// Such a size will induce out of memory errors for incorrect
// slice implementations
withData(longs()).
stream(s -> fs.apply(s.filter(i -> true).unordered().boxed())).
resultAsserter(unorderedAsserter()).
exercise();
}
@Test(dataProvider = "IntStream.limit")
public void testIntUnorderedFinite(String description, UnaryOperator<IntStream> fs) {
// Range is [0, Integer.MAX_VALUE), splits are SUBSIZED
// Such a size will induce out of memory errors for incorrect
// slice implementations
withData(ints()).
stream(s -> fs.apply(s.filter(i -> true).unordered())).
resultAsserter(unorderedAsserter()).
exercise();
}
@Test(dataProvider = "LongStream.limit")
public void testLongUnorderedFinite(String description, UnaryOperator<LongStream> fs) {
// Range is [0, Long.MAX_VALUE), splits are SUBSIZED
// Such a size will induce out of memory errors for incorrect
// slice implementations
withData(longs()).
stream(s -> fs.apply(s.filter(i -> true).unordered())).
resultAsserter(unorderedAsserter()).
exercise();
}
@Test(dataProvider = "DoubleStream.limit")
public void testDoubleUnorderedFinite(String description, UnaryOperator<DoubleStream> fs) {
// Range is [0, 1L << 53), splits are SUBSIZED
// Such a size will induce out of memory errors for incorrect
// slice implementations
// Upper bound ensures values mapped to doubles will be unique
withData(doubles()).
stream(s -> fs.apply(s.filter(i -> true).unordered())).
resultAsserter(unorderedAsserter()).
exercise();
}
// Unordered finite not SUBSIZED
@SuppressWarnings({"rawtypes", "unchecked"})
private Spliterator.OfLong proxyNotSubsized(Spliterator.OfLong s) {
InvocationHandler ih = new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
switch (method.getName()) {
case "characteristics": {
int c = (Integer) method.invoke(s, args);
return c & ~Spliterator.SUBSIZED;
}
case "hasCharacteristics": {
int c = (Integer) args[0];
boolean b = (Boolean) method.invoke(s, args);
return b & ((c & Spliterator.SUBSIZED) == 0);
}
default:
return method.invoke(s, args);
}
}
};
return (Spliterator.OfLong) Proxy.newProxyInstance(this.getClass().getClassLoader(),
new Class[]{Spliterator.OfLong.class},
ih);
}
private TestData.OfLong proxiedLongRange(long l, long u) {
return TestData.Factory.ofLongSupplier(
String.format("[%d, %d)", l, u),
() -> StreamSupport.longStream(proxyNotSubsized(LongStream.range(l, u).spliterator()), false));
}
@Test(dataProvider = "Stream.limit")
public void testUnorderedSizedNotSubsizedFinite(String description, UnaryOperator<Stream<Long>> fs) {
// Range is [0, Long.MAX_VALUE), splits are not SUBSIZED (proxy clears
// the SUBSIZED characteristic)
// Such a size will induce out of memory errors for incorrect
// slice implementations
withData(proxiedLongRange(0, Long.MAX_VALUE)).
stream(s -> fs.apply(s.unordered().boxed())).
resultAsserter(unorderedAsserter()).
exercise();
}
@Test(dataProvider = "IntStream.limit")
public void testIntUnorderedSizedNotSubsizedFinite(String description, UnaryOperator<IntStream> fs) {
// Range is [0, Integer.MAX_VALUE), splits are not SUBSIZED (proxy clears
// the SUBSIZED characteristic)
// Such a size will induce out of memory errors for incorrect
// slice implementations
withData(proxiedLongRange(0, Integer.MAX_VALUE)).
stream(s -> fs.apply(s.unordered().mapToInt(i -> (int) i))).
resultAsserter(unorderedAsserter()).
exercise();
}
@Test(dataProvider = "LongStream.limit")
public void testLongUnorderedSizedNotSubsizedFinite(String description, UnaryOperator<LongStream> fs) {
// Range is [0, Long.MAX_VALUE), splits are not SUBSIZED (proxy clears
// the SUBSIZED characteristic)
// Such a size will induce out of memory errors for incorrect
// slice implementations
withData(proxiedLongRange(0, Long.MAX_VALUE)).
stream(s -> fs.apply(s.unordered())).
resultAsserter(unorderedAsserter()).
exercise();
}
@Test(dataProvider = "DoubleStream.limit")
public void testDoubleUnorderedSizedNotSubsizedFinite(String description, UnaryOperator<DoubleStream> fs) {
// Range is [0, Double.MAX_VALUE), splits are not SUBSIZED (proxy clears
// the SUBSIZED characteristic)
// Such a size will induce out of memory errors for incorrect
// slice implementations
withData(proxiedLongRange(0, 1L << 53)).
stream(s -> fs.apply(s.unordered().mapToDouble(i -> (double) i))).
resultAsserter(unorderedAsserter()).
exercise();
}
// Unordered generation
@Test(dataProvider = "Stream.limit")
public void testUnorderedGenerator(String description, UnaryOperator<Stream<Long>> fs) {
// Source is spliterator of infinite size
TestData.OfRef<Long> generator = TestData.Factory.ofSupplier(
"[1L, 1L, ...]", () -> Stream.generate(() -> 1L));
withData(generator).
stream(s -> fs.apply(s.filter(i -> true).unordered())).
exercise();
}
@Test(dataProvider = "IntStream.limit")
public void testIntUnorderedGenerator(String description, UnaryOperator<IntStream> fs) {
// Source is spliterator of infinite size
TestData.OfInt generator = TestData.Factory.ofIntSupplier(
"[1, 1, ...]", () -> IntStream.generate(() -> 1));
withData(generator).
stream(s -> fs.apply(s.filter(i -> true).unordered())).
exercise();
}
@Test(dataProvider = "LongStream.limit")
public void testLongUnorderedGenerator(String description, UnaryOperator<LongStream> fs) {
// Source is spliterator of infinite size
TestData.OfLong generator = TestData.Factory.ofLongSupplier(
"[1L, 1L, ...]", () -> LongStream.generate(() -> 1));
withData(generator).
stream(s -> fs.apply(s.filter(i -> true).unordered())).
exercise();
}
@Test(dataProvider = "DoubleStream.limit")
public void testDoubleUnorderedGenerator(String description, UnaryOperator<DoubleStream> fs) {
// Source is spliterator of infinite size
TestData.OfDouble generator = TestData.Factory.ofDoubleSupplier(
"[1.0, 1.0, ...]", () -> DoubleStream.generate(() -> 1.0));
withData(generator).
stream(s -> fs.apply(s.filter(i -> true).unordered())).
exercise();
}
// Unordered iteration
@Test(dataProvider = "Stream.limit")
public void testUnorderedIteration(String description, UnaryOperator<Stream<Long>> fs) {
// Source is a right-balanced tree of infinite size
TestData.OfRef<Long> iterator = TestData.Factory.ofSupplier(
"[1L, 2L, 3L, ...]", () -> Stream.iterate(1L, i -> i + 1L));
// Ref
withData(iterator).
stream(s -> fs.apply(s.unordered())).
resultAsserter(unorderedAsserter()).
exercise();
}
@Test(dataProvider = "IntStream.limit")
public void testIntUnorderedIteration(String description, UnaryOperator<IntStream> fs) {
// Source is a right-balanced tree of infinite size
TestData.OfInt iterator = TestData.Factory.ofIntSupplier(
"[1, 2, 3, ...]", () -> IntStream.iterate(1, i -> i + 1));
// Ref
withData(iterator).
stream(s -> fs.apply(s.unordered())).
resultAsserter(unorderedAsserter()).
exercise();
}
@Test(dataProvider = "LongStream.limit")
public void testLongUnorderedIteration(String description, UnaryOperator<LongStream> fs) {
// Source is a right-balanced tree of infinite size
TestData.OfLong iterator = TestData.Factory.ofLongSupplier(
"[1L, 2L, 3L, ...]", () -> LongStream.iterate(1, i -> i + 1));
// Ref
withData(iterator).
stream(s -> fs.apply(s.unordered())).
resultAsserter(unorderedAsserter()).
exercise();
}
@Test(dataProvider = "DoubleStream.limit")
public void testDoubleUnorderedIteration(String description, UnaryOperator<DoubleStream> fs) {
// Source is a right-balanced tree of infinite size
TestData.OfDouble iterator = TestData.Factory.ofDoubleSupplier(
"[1.0, 2.0, 3.0, ...]", () -> DoubleStream.iterate(1, i -> i + 1));
// Ref
withData(iterator).
stream(s -> fs.apply(s.unordered())).
resultAsserter(unorderedAsserter()).
exercise();
}
}

View file

@ -0,0 +1,243 @@
/*
* Copyright (c) 2012, 2013, 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.
*/
package org.openjdk.tests.java.util.stream;
import org.testng.Assert;
import org.testng.annotations.Test;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.Spliterator;
import java.util.TreeSet;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.IntConsumer;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertTrue;
/**
* @test
* @bug 8153293
*/
@Test
public class IntPrimitiveOpsTests {
public void testSum() {
long sum = IntStream.range(1, 10).filter(i -> i % 2 == 0).sum();
assertEquals(sum, 20);
}
public void testMap() {
long sum = IntStream.range(1, 10).filter(i -> i % 2 == 0).map(i -> i * 2).sum();
assertEquals(sum, 40);
}
public void testParSum() {
long sum = IntStream.range(1, 10).parallel().filter(i -> i % 2 == 0).sum();
assertEquals(sum, 20);
}
@Test(groups = { "serialization-hostile" })
public void testTee() {
int[] teeSum = new int[1];
long sum = IntStream.range(1, 10).filter(i -> i % 2 == 0).peek(i -> { teeSum[0] = teeSum[0] + i; }).sum();
assertEquals(teeSum[0], sum);
}
@Test(groups = { "serialization-hostile" })
public void testForEach() {
int[] sum = new int[1];
IntStream.range(1, 10).filter(i -> i % 2 == 0).forEach(i -> { sum[0] = sum[0] + i; });
assertEquals(sum[0], 20);
}
@Test(groups = { "serialization-hostile" })
public void testParForEach() {
AtomicInteger ai = new AtomicInteger(0);
IntStream.range(1, 10).parallel().filter(i -> i % 2 == 0).forEach(ai::addAndGet);
assertEquals(ai.get(), 20);
}
public void testBox() {
List<Integer> l = IntStream.range(1, 10).parallel().boxed().collect(Collectors.toList());
int sum = l.stream().reduce(0, (a, b) -> a + b);
assertEquals(sum, 45);
}
public void testUnBox() {
long sum = Arrays.asList(1, 2, 3, 4, 5).stream().mapToInt(i -> (int) i).sum();
assertEquals(sum, 15);
}
public void testFlags() {
assertTrue(IntStream.range(1, 10).boxed().spliterator()
.hasCharacteristics(Spliterator.SORTED | Spliterator.DISTINCT));
assertFalse(IntStream.of(1, 10).boxed().spliterator()
.hasCharacteristics(Spliterator.SORTED));
assertFalse(IntStream.of(1, 10).boxed().spliterator()
.hasCharacteristics(Spliterator.DISTINCT));
assertTrue(IntStream.range(1, 10).asLongStream().spliterator()
.hasCharacteristics(Spliterator.SORTED | Spliterator.DISTINCT));
assertFalse(IntStream.of(1, 10).asLongStream().spliterator()
.hasCharacteristics(Spliterator.SORTED));
assertFalse(IntStream.of(1, 10).asLongStream().spliterator()
.hasCharacteristics(Spliterator.DISTINCT));
assertTrue(IntStream.range(1, 10).asDoubleStream().spliterator()
.hasCharacteristics(Spliterator.SORTED | Spliterator.DISTINCT));
assertFalse(IntStream.of(1, 10).asDoubleStream().spliterator()
.hasCharacteristics(Spliterator.SORTED));
assertFalse(IntStream.of(1, 10).asDoubleStream().spliterator()
.hasCharacteristics(Spliterator.DISTINCT));
}
public void testToArray() {
{
int[] array = IntStream.range(1, 10).map(i -> i * 2).toArray();
assertEquals(array, new int[]{2, 4, 6, 8, 10, 12, 14, 16, 18});
}
{
int[] array = IntStream.range(1, 10).parallel().map(i -> i * 2).toArray();
assertEquals(array, new int[]{2, 4, 6, 8, 10, 12, 14, 16, 18});
}
}
public void testSort() {
Random r = new Random();
int[] content = IntStream.generate(() -> r.nextInt(100)).limit(10).toArray();
int[] sortedContent = content.clone();
Arrays.sort(sortedContent);
{
int[] array = Arrays.stream(content).sorted().toArray();
assertEquals(array, sortedContent);
}
{
int[] array = Arrays.stream(content).parallel().sorted().toArray();
assertEquals(array, sortedContent);
}
}
public void testSortDistinct() {
{
int[] range = IntStream.range(0, 10).toArray();
assertEquals(IntStream.range(0, 10).sorted().distinct().toArray(), range);
assertEquals(IntStream.range(0, 10).parallel().sorted().distinct().toArray(), range);
int[] data = {5, 3, 1, 1, 5, 3, 9, 2, 9, 1, 0, 8};
int[] expected = {0, 1, 2, 3, 5, 8, 9};
assertEquals(IntStream.of(data).sorted().distinct().toArray(), expected);
assertEquals(IntStream.of(data).parallel().sorted().distinct().toArray(), expected);
}
{
int[] input = new Random().ints(100, -10, 10).map(x -> x+Integer.MAX_VALUE).toArray();
TreeSet<Long> longs = new TreeSet<>();
for(int i : input) longs.add((long)i);
long[] expectedLongs = longs.stream().mapToLong(Long::longValue).toArray();
assertEquals(IntStream.of(input).sorted().asLongStream().sorted().distinct().toArray(),
expectedLongs);
TreeSet<Double> doubles = new TreeSet<>();
for(int i : input) doubles.add((double)i);
double[] expectedDoubles = doubles.stream().mapToDouble(Double::doubleValue).toArray();
assertEquals(IntStream.of(input).sorted().distinct().asDoubleStream()
.sorted().distinct().toArray(), expectedDoubles);
}
}
public void testSortSort() {
Random r = new Random();
int[] content = IntStream.generate(() -> r.nextInt(100)).limit(10).toArray();
int[] sortedContent = content.clone();
Arrays.sort(sortedContent);
{
int[] array = Arrays.stream(content).sorted().sorted().toArray();
assertEquals(array, sortedContent);
}
{
int[] array = Arrays.stream(content).parallel().sorted().sorted().toArray();
assertEquals(array, sortedContent);
}
}
public void testSequential() {
int[] expected = IntStream.range(1, 1000).toArray();
class AssertingConsumer implements IntConsumer {
private final int[] array;
int offset;
AssertingConsumer(int[] array) {
this.array = array;
}
@Override
public void accept(int value) {
assertEquals(array[offset++], value);
}
public int getCount() { return offset; }
}
{
AssertingConsumer consumer = new AssertingConsumer(expected);
IntStream.range(1, 1000).sequential().forEach(consumer);
assertEquals(expected.length, consumer.getCount());
}
{
AssertingConsumer consumer = new AssertingConsumer(expected);
IntStream.range(1, 1000).parallel().sequential().forEach(consumer);
assertEquals(expected.length, consumer.getCount());
}
}
public void testLimit() {
int[] expected = IntStream.range(1, 10).toArray();
{
int[] actual = IntStream.iterate(1, i -> i + 1).limit(9).toArray();
Assert.assertTrue(Arrays.equals(expected, actual));
}
{
int[] actual = IntStream.range(1, 100).parallel().limit(9).toArray();
Assert.assertTrue(Arrays.equals(expected, actual));
}
}
}

View file

@ -0,0 +1,81 @@
/*
* Copyright (c) 2012, 2013, 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.
*/
package org.openjdk.tests.java.util.stream;
import java.util.stream.IntStream;
import java.util.stream.IntStreamTestDataProvider;
import java.util.stream.OpTestCase;
import org.testng.annotations.Test;
import java.util.Arrays;
import java.util.OptionalInt;
import java.util.stream.TestData;
import static java.util.stream.LambdaTestHelpers.*;
public class IntReduceTest extends OpTestCase {
public void testReduce() {
int[] a = IntStream.range(1, 11).toArray();
assertEquals(55, Arrays.stream(a).reduce(irPlus).getAsInt());
assertEquals(55, Arrays.stream(a).reduce(0, irPlus));
assertEquals(10, Arrays.stream(a).reduce(irMax).getAsInt());
assertEquals(1, Arrays.stream(a).reduce(irMin).getAsInt());
assertEquals(0, IntStream.empty().reduce(0, irPlus));
assertFalse(IntStream.empty().reduce(irPlus).isPresent());
assertEquals(110, Arrays.stream(a).map(irDoubler).reduce(irPlus).getAsInt());
assertEquals(20, Arrays.stream(a).map(irDoubler).reduce(irMax).getAsInt());
assertEquals(2, Arrays.stream(a).map(irDoubler).reduce(irMin).getAsInt());
}
@Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
public void testOps(String name, TestData.OfInt data) {
assertEquals(0, (int) exerciseTerminalOps(data, s -> s.filter(ipFalse), s -> s.reduce(0, irPlus)));
OptionalInt seedless = exerciseTerminalOps(data, s -> s.reduce(irPlus));
int folded = exerciseTerminalOps(data, s -> s.reduce(0, irPlus));
assertEquals(folded, seedless.orElse(0));
seedless = exerciseTerminalOps(data, s -> s.reduce(irMin));
folded = exerciseTerminalOps(data, s -> s.reduce(Integer.MAX_VALUE, irMin));
assertEquals(folded, seedless.orElse(Integer.MAX_VALUE));
seedless = exerciseTerminalOps(data, s -> s.reduce(irMax));
folded = exerciseTerminalOps(data, s -> s.reduce(Integer.MIN_VALUE, irMax));
assertEquals(folded, seedless.orElse(Integer.MIN_VALUE));
seedless = exerciseTerminalOps(data, s -> s.map(irDoubler), s -> s.reduce(irPlus));
folded = exerciseTerminalOps(data, s -> s.map(irDoubler), s -> s.reduce(0, irPlus));
assertEquals(folded, seedless.orElse(0));
seedless = exerciseTerminalOps(data, s -> s.map(irDoubler), s -> s.reduce(irMin));
folded = exerciseTerminalOps(data, s -> s.map(irDoubler), s -> s.reduce(Integer.MAX_VALUE, irMin));
assertEquals(folded, seedless.orElse(Integer.MAX_VALUE));
seedless = exerciseTerminalOps(data, s -> s.map(irDoubler), s -> s.reduce(irMax));
folded = exerciseTerminalOps(data, s -> s.map(irDoubler), s -> s.reduce(Integer.MIN_VALUE, irMax));
assertEquals(folded, seedless.orElse(Integer.MIN_VALUE));
}
}

View file

@ -0,0 +1,208 @@
/*
* Copyright (c) 2012, 2013, 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.
*/
package org.openjdk.tests.java.util.stream;
import java.util.Collection;
import java.util.stream.*;
import org.testng.annotations.Test;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import static java.util.stream.LambdaTestHelpers.assertCountSum;
/**
* SliceOpTest
*
* @author Brian Goetz
*/
@Test
public class IntSliceOpTest extends OpTestCase {
private static final int[] EMPTY_INT_ARRAY = new int[0];
public void testSkip() {
assertCountSum(IntStream.range(0, 0).skip(0).boxed(), 0, 0);
assertCountSum(IntStream.range(0, 0).skip(4).boxed(), 0, 0);
assertCountSum(IntStream.range(1, 5).skip(4).boxed(), 0, 0);
assertCountSum(IntStream.range(1, 5).skip(2).boxed(), 2, 7);
assertCountSum(IntStream.range(1, 5).skip(0).boxed(), 4, 10);
assertCountSum(IntStream.range(0, 0).parallel().skip(0).boxed(), 0, 0);
assertCountSum(IntStream.range(0, 0).parallel().skip(4).boxed(), 0, 0);
assertCountSum(IntStream.range(1, 5).parallel().skip(4).boxed(), 0, 0);
assertCountSum(IntStream.range(1, 5).parallel().skip(2).boxed(), 2, 7);
assertCountSum(IntStream.range(1, 5).parallel().skip(0).boxed(), 4, 10);
exerciseOps(EMPTY_INT_ARRAY, s -> s.skip(0), EMPTY_INT_ARRAY);
exerciseOps(EMPTY_INT_ARRAY, s -> s.skip(10), EMPTY_INT_ARRAY);
exerciseOps(IntStream.range(1, 2).toArray(), s -> s.skip(0), IntStream.range(1, 2).toArray());
exerciseOps(IntStream.range(1, 2).toArray(), s -> s.skip(1), EMPTY_INT_ARRAY);
exerciseOps(IntStream.range(1, 101).toArray(), s -> s.skip(0), IntStream.range(1, 101).toArray());
exerciseOps(IntStream.range(1, 101).toArray(), s -> s.skip(10), IntStream.range(11, 101).toArray());
exerciseOps(IntStream.range(1, 101).toArray(), s -> s.skip(100), EMPTY_INT_ARRAY);
exerciseOps(IntStream.range(1, 101).toArray(), s -> s.skip(200), EMPTY_INT_ARRAY);
}
public void testLimit() {
assertCountSum(IntStream.range(0, 0).limit(4).boxed(), 0, 0);
assertCountSum(IntStream.range(1, 3).limit(4).boxed(), 2, 3);
assertCountSum(IntStream.range(1, 5).limit(4).boxed(), 4, 10);
assertCountSum(IntStream.range(1, 9).limit(4).boxed(), 4, 10);
assertCountSum(IntStream.range(0, 0).parallel().limit(4).boxed(), 0, 0);
assertCountSum(IntStream.range(1, 3).parallel().limit(4).boxed(), 2, 3);
assertCountSum(IntStream.range(1, 5).parallel().limit(4).boxed(), 4, 10);
assertCountSum(IntStream.range(1, 9).parallel().limit(4).boxed(), 4, 10);
exerciseOps(EMPTY_INT_ARRAY, s -> s.limit(0), EMPTY_INT_ARRAY);
exerciseOps(EMPTY_INT_ARRAY, s -> s.limit(10), EMPTY_INT_ARRAY);
exerciseOps(IntStream.range(1, 2).toArray(), s -> s.limit(0), EMPTY_INT_ARRAY);
exerciseOps(IntStream.range(1, 2).toArray(), s -> s.limit(1), IntStream.range(1, 2).toArray());
exerciseOps(IntStream.range(1, 101).toArray(), s -> s.limit(0), EMPTY_INT_ARRAY);
exerciseOps(IntStream.range(1, 101).toArray(), s -> s.limit(10), IntStream.range(1, 11).toArray());
exerciseOps(IntStream.range(1, 101).toArray(), s -> s.limit(10).limit(10), IntStream.range(1, 11).toArray());
exerciseOps(IntStream.range(1, 101).toArray(), s -> s.limit(100), IntStream.range(1, 101).toArray());
exerciseOps(IntStream.range(1, 101).toArray(), s -> s.limit(100).limit(10), IntStream.range(1, 11).toArray());
exerciseOps(IntStream.range(1, 101).toArray(), s -> s.limit(200), IntStream.range(1, 101).toArray());
}
public void testSkipLimit() {
exerciseOps(EMPTY_INT_ARRAY, s -> s.skip(0).limit(0), EMPTY_INT_ARRAY);
exerciseOps(EMPTY_INT_ARRAY, s -> s.skip(0).limit(10), EMPTY_INT_ARRAY);
exerciseOps(EMPTY_INT_ARRAY, s -> s.skip(10).limit(0), EMPTY_INT_ARRAY);
exerciseOps(EMPTY_INT_ARRAY, s -> s.skip(10).limit(10), EMPTY_INT_ARRAY);
exerciseOps(IntStream.range(1, 101).toArray(), s -> s.skip(0).limit(100), IntStream.range(1, 101).toArray());
exerciseOps(IntStream.range(1, 101).toArray(), s -> s.skip(0).limit(10), IntStream.range(1, 11).toArray());
exerciseOps(IntStream.range(1, 101).toArray(), s -> s.skip(0).limit(0), EMPTY_INT_ARRAY);
exerciseOps(IntStream.range(1, 101).toArray(), s -> s.skip(10).limit(100), IntStream.range(11, 101).toArray());
exerciseOps(IntStream.range(1, 101).toArray(), s -> s.skip(10).limit(10), IntStream.range(11, 21).toArray());
exerciseOps(IntStream.range(1, 101).toArray(), s -> s.skip(10).limit(0), EMPTY_INT_ARRAY);
exerciseOps(IntStream.range(1, 101).toArray(), s -> s.skip(100).limit(100), EMPTY_INT_ARRAY);
exerciseOps(IntStream.range(1, 101).toArray(), s -> s.skip(100).limit(10), EMPTY_INT_ARRAY);
exerciseOps(IntStream.range(1, 101).toArray(), s -> s.skip(100).limit(0), EMPTY_INT_ARRAY);
exerciseOps(IntStream.range(1, 101).toArray(), s -> s.skip(200).limit(100), EMPTY_INT_ARRAY);
exerciseOps(IntStream.range(1, 101).toArray(), s -> s.skip(200).limit(10), EMPTY_INT_ARRAY);
exerciseOps(IntStream.range(1, 101).toArray(), s -> s.skip(200).limit(0), EMPTY_INT_ARRAY);
}
private int sliceSize(int dataSize, int skip, int limit) {
int size = Math.max(0, dataSize - skip);
if (limit >= 0)
size = Math.min(size, limit);
return size;
}
private int sliceSize(int dataSize, int skip) {
return Math.max(0, dataSize - skip);
}
@Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
public void testSkipOps(String name, TestData.OfInt data) {
List<Integer> skips = sizes(data.size());
for (int s : skips) {
setContext("skip", s);
Collection<Integer> sr = exerciseOps(data, st -> st.skip(s));
assertEquals(sr.size(), sliceSize(data.size(), s));
sr = exerciseOps(data, st -> st.skip(s).skip(s / 2));
assertEquals(sr.size(), sliceSize(sliceSize(data.size(), s), s / 2));
}
}
@Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
public void testSkipLimitOps(String name, TestData.OfInt data) {
List<Integer> skips = sizes(data.size());
List<Integer> limits = skips;
for (int s : skips) {
setContext("skip", s);
for (int limit : limits) {
setContext("limit", limit);
Collection<Integer> sr = exerciseOps(data, st -> st.skip(s).limit(limit));
assertEquals(sr.size(), sliceSize(sliceSize(data.size(), s), 0, limit));
sr = exerciseOps(data, st -> st.skip(s).limit(limit));
assertEquals(sr.size(), sliceSize(data.size(), s, limit));
}
}
}
@Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
public void testLimitOps(String name, TestData.OfInt data) {
List<Integer> limits = sizes(data.size());
for (int limit : limits) {
setContext("limit", limit);
Collection<Integer> sr = exerciseOps(data, st -> st.limit(limit));
assertEquals(sr.size(), sliceSize(data.size(), 0, limit));
sr = exerciseOps(data, st -> st.limit(limit).limit(limit / 2));
assertEquals(sr.size(), sliceSize(sliceSize(data.size(), 0, limit), 0, limit / 2));
}
}
public void testLimitSort() {
exerciseOps(IntStream.range(1, 101).map(i -> 101 - i).toArray(), s -> s.limit(10).sorted());
}
@Test(groups = { "serialization-hostile" })
public void testLimitShortCircuit() {
for (int l : Arrays.asList(0, 10)) {
setContext("limit", l);
AtomicInteger ai = new AtomicInteger();
IntStream.range(1, 101)
.peek(i -> ai.getAndIncrement())
.limit(l).toArray();
// For the case of a zero limit, one element will get pushed through the sink chain
assertEquals(ai.get(), l, "tee block was called too many times");
}
}
public void testSkipParallel() {
int[] l = IntStream.range(1, 1001).parallel().skip(200).limit(200).sequential().toArray();
assertEquals(l.length, 200);
assertEquals(l[l.length - 1], 400);
}
public void testLimitParallel() {
int[] l = IntStream.range(1, 1001).parallel().limit(500).sequential().toArray();
assertEquals(l.length, 500);
assertEquals(l[l.length - 1], 500);
}
private List<Integer> sizes(int size) {
if (size < 4) {
return Arrays.asList(0, 1, 2, 3, 4, 6);
}
else {
return Arrays.asList(0, 1, size / 2, size - 1, size, size + 1, 2 * size);
}
}
}

View file

@ -0,0 +1,72 @@
/*
* Copyright (c) 2012, 2013, 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.
*/
package org.openjdk.tests.java.util.stream;
import java.util.Collection;
import java.util.stream.*;
import org.testng.annotations.Test;
import static java.util.stream.LambdaTestHelpers.assertCountSum;
import static java.util.stream.LambdaTestHelpers.assertUnique;
/**
* UniqOpTest
*/
@Test
public class IntUniqOpTest extends OpTestCase {
public void testUniqOp() {
assertCountSum(IntStream.generate(() -> 0).limit(10).distinct().boxed(), 1, 0);
assertCountSum(IntStream.generate(() -> 1).limit(10).distinct().boxed(), 1, 1);
assertCountSum(IntStream.range(0, 0).distinct().boxed(), 0, 0);
assertCountSum(IntStream.range(1, 11).distinct().boxed(), 10, 55);
assertCountSum(IntStream.range(1, 11).distinct().boxed(), 10, 55);
}
@Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
public void testOp(String name, TestData.OfInt data) {
Collection<Integer> result = exerciseOps(data, s -> s.distinct().boxed());
assertUnique(result);
if (data.size() > 0)
assertTrue(result.size() > 0);
else
assertTrue(result.size() == 0);
assertTrue(result.size() <= data.size());
}
@Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
public void testOpSorted(String name, TestData.OfInt data) {
Collection<Integer> result = withData(data).
stream(s -> s.sorted().distinct().boxed()).
exercise();
assertUnique(result);
if (data.size() > 0)
assertTrue(result.size() > 0);
else
assertTrue(result.size() == 0);
assertTrue(result.size() <= data.size());
}
}

View file

@ -0,0 +1,118 @@
/*
* Copyright (c) 2016, 2022, 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.Collector;
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.ThrowableHelper.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));
}
@Test
public void testParallelize() {
checkHasSplit(Stream.iterate(0, x -> x < 10, x -> x + 1));
checkHasSplit(IntStream.iterate(0, x -> x < 10, x -> x + 1).boxed());
checkHasSplit(LongStream.iterate(0, x -> x < 10, x -> x + 1).boxed());
checkHasSplit(DoubleStream.iterate(0, x -> x < 10, x -> x + 1).boxed());
}
private void checkHasSplit(Stream<?> stream) {
int[] numberOfNonEmptyParts = stream.parallel().collect(
Collector.of(() -> new int[1], (acc, e) -> acc[0] = 1, (acc1, acc2) -> {
acc1[0] += acc2[0];
return acc1;
}));
assertTrue(numberOfNonEmptyParts[0] >= 2);
}
}

View file

@ -0,0 +1,231 @@
/*
* Copyright (c) 2012, 2013, 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.
*/
package org.openjdk.tests.java.util.stream;
import org.testng.Assert;
import org.testng.annotations.Test;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.Spliterator;
import java.util.TreeSet;
import java.util.concurrent.atomic.AtomicLong;
import java.util.function.LongConsumer;
import java.util.stream.Collectors;
import java.util.stream.LongStream;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertTrue;
/**
* @test
* @bug 8153293
*/
@Test
public class LongPrimitiveOpsTests {
public void testSum() {
long sum = LongStream.range(1, 10).filter(i -> i % 2 == 0).sum();
assertEquals(sum, 20);
}
public void testMap() {
long sum = LongStream.range(1, 10).filter(i -> i % 2 == 0).map(i -> i * 2).sum();
assertEquals(sum, 40);
}
public void testParSum() {
long sum = LongStream.range(1, 10).parallel().filter(i -> i % 2 == 0).sum();
assertEquals(sum, 20);
}
@Test(groups = { "serialization-hostile" })
public void testTee() {
long[] teeSum = new long[1];
long sum = LongStream.range(1, 10).filter(i -> i % 2 == 0).peek(i -> { teeSum[0] = teeSum[0] + i; }).sum();
assertEquals(teeSum[0], sum);
}
@Test(groups = { "serialization-hostile" })
public void testForEach() {
long[] sum = new long[1];
LongStream.range(1, 10).filter(i -> i % 2 == 0).forEach(i -> { sum[0] = sum[0] + i; });
assertEquals(sum[0], 20);
}
@Test(groups = { "serialization-hostile" })
public void testParForEach() {
AtomicLong ai = new AtomicLong(0);
LongStream.range(1, 10).parallel().filter(i -> i % 2 == 0).forEach(ai::addAndGet);
assertEquals(ai.get(), 20);
}
public void testBox() {
List<Long> l = LongStream.range(1, 10).parallel().boxed().collect(Collectors.toList());
long sum = l.stream().reduce(0L, (a, b) -> a + b);
assertEquals(sum, 45);
}
public void testUnBox() {
long sum = Arrays.asList(1L, 2L, 3L, 4L, 5L).stream().mapToLong(i -> (long) i).sum();
assertEquals(sum, 15);
}
public void testFlags() {
assertTrue(LongStream.range(1, 10).boxed().spliterator()
.hasCharacteristics(Spliterator.SORTED | Spliterator.DISTINCT));
assertFalse(LongStream.of(1, 10).boxed().spliterator()
.hasCharacteristics(Spliterator.SORTED));
assertFalse(LongStream.of(1, 10).boxed().spliterator()
.hasCharacteristics(Spliterator.DISTINCT));
assertTrue(LongStream.range(1, 10).asDoubleStream().spliterator()
.hasCharacteristics(Spliterator.SORTED));
assertFalse(LongStream.range(1, 10).asDoubleStream().spliterator()
.hasCharacteristics(Spliterator.DISTINCT));
assertFalse(LongStream.of(1, 10).asDoubleStream().spliterator()
.hasCharacteristics(Spliterator.SORTED));
}
public void testToArray() {
{
long[] array = LongStream.range(1, 10).map(i -> i * 2).toArray();
assertEquals(array, new long[]{2, 4, 6, 8, 10, 12, 14, 16, 18});
}
{
long[] array = LongStream.range(1, 10).parallel().map(i -> i * 2).toArray();
assertEquals(array, new long[]{2, 4, 6, 8, 10, 12, 14, 16, 18});
}
}
public void testSort() {
Random r = new Random();
long[] content = LongStream.generate(() -> r.nextLong()).limit(10).toArray();
long[] sortedContent = content.clone();
Arrays.sort(sortedContent);
{
long[] array = Arrays.stream(content).sorted().toArray();
assertEquals(array, sortedContent);
}
{
long[] array = Arrays.stream(content).parallel().sorted().toArray();
assertEquals(array, sortedContent);
}
}
public void testSortDistinct() {
{
long[] range = LongStream.range(0, 10).toArray();
assertEquals(LongStream.range(0, 10).sorted().distinct().toArray(), range);
assertEquals(LongStream.range(0, 10).parallel().sorted().distinct().toArray(), range);
long[] data = {5, 3, 1, 1, 5, 3, 9, 2, 9, 1, 0, 8};
long[] expected = {0, 1, 2, 3, 5, 8, 9};
assertEquals(LongStream.of(data).sorted().distinct().toArray(), expected);
assertEquals(LongStream.of(data).parallel().sorted().distinct().toArray(), expected);
}
{
long[] input = new Random().longs(100, -10, 10).map(x -> x+Long.MAX_VALUE).toArray();
TreeSet<Double> doubles = new TreeSet<>();
for(long i : input) doubles.add((double)i);
double[] expectedDoubles = doubles.stream().mapToDouble(Double::doubleValue).toArray();
assertEquals(LongStream.of(input).sorted().distinct().asDoubleStream()
.sorted().distinct().toArray(), expectedDoubles);
}
}
public void testSortSort() {
Random r = new Random();
long[] content = LongStream.generate(() -> r.nextLong()).limit(10).toArray();
long[] sortedContent = content.clone();
Arrays.sort(sortedContent);
{
long[] array = Arrays.stream(content).sorted().sorted().toArray();
assertEquals(array, sortedContent);
}
{
long[] array = Arrays.stream(content).parallel().sorted().sorted().toArray();
assertEquals(array, sortedContent);
}
}
public void testSequential() {
long[] expected = LongStream.range(1, 1000).toArray();
class AssertingConsumer implements LongConsumer {
private final long[] array;
int offset;
AssertingConsumer(long[] array) {
this.array = array;
}
@Override
public void accept(long value) {
assertEquals(array[offset++], value);
}
public int getCount() { return offset; }
}
{
AssertingConsumer consumer = new AssertingConsumer(expected);
LongStream.range(1, 1000).sequential().forEach(consumer);
assertEquals(expected.length, consumer.getCount());
}
{
AssertingConsumer consumer = new AssertingConsumer(expected);
LongStream.range(1, 1000).parallel().sequential().forEach(consumer);
assertEquals(expected.length, consumer.getCount());
}
}
public void testLimit() {
long[] expected = LongStream.range(1, 10).toArray();
{
long[] actual = LongStream.iterate(1, i -> i + 1).limit(9).toArray();
Assert.assertTrue(Arrays.equals(expected, actual));
}
{
long[] actual = LongStream.range(1, 100).parallel().limit(9).toArray();
Assert.assertTrue(Arrays.equals(expected, actual));
}
}
}

View file

@ -0,0 +1,125 @@
/*
* Copyright (c) 2012, 2013, 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.
*/
package org.openjdk.tests.java.util.stream;
import org.testng.annotations.Test;
import java.util.stream.*;
import static java.util.stream.LambdaTestHelpers.*;
/**
* MapOpTest
*
* @author Brian Goetz
*/
@Test
public class MapOpTest extends OpTestCase {
public void testMap() {
assertCountSum(countTo(0).stream().map(mId), 0, 0);
assertCountSum(countTo(10).stream().map(mId), 10, 55);
assertCountSum(countTo(10).stream().map(mZero), 10, 0);
assertCountSum(countTo(0).stream().map(mDoubler), 0, 0);
assertCountSum(countTo(10).stream().map(mDoubler), 10, 110);
assertCountSum(countTo(10).stream().map(mDoubler).map(mDoubler), 10, 220);
exerciseOps(countTo(0), s -> s.map(LambdaTestHelpers.identity()), countTo(0));
exerciseOps(countTo(1000), s -> s.map(LambdaTestHelpers.identity()), countTo(1000));
// @@@ Force cast to integer so output is Stream<Integer> rather an IntStream
// this just ensures that no warnings are logged about boxing
// when the result is compared with the output
exerciseOps(countTo(1000), s -> s.map(e -> (Integer) (1000 + e)), range(1001, 2000));
}
public void testEveryMapShape() {
assertCountSum(countTo(1000).stream()
.mapToInt(i -> i - 1)
.mapToObj(i -> i + 1)
.mapToLong(i -> i - 1)
.mapToObj(i -> i + 1)
.mapToDouble(i -> i - 1)
.mapToObj(i -> i + 1)
.mapToInt(i -> (int) (double) i)
.mapToLong(i -> i)
.mapToDouble(i -> i)
.mapToLong(i -> (long) i)
.mapToInt(i -> (int) i)
.mapToObj(i -> i),
1000, countTo(1000).stream().mapToInt(i -> i).sum());
}
@Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
public void testOps(String name, TestData.OfRef<Integer> data) {
exerciseOpsInt(data, s -> s.map(mId), s -> s.map(e -> e), s -> s.map(e -> e), s -> s.map(e -> e));
exerciseOpsInt(data, s -> s.map(mZero), s -> s.map(e -> 0), s -> s.map(e -> 0), s -> s.map(e -> 0));
exerciseOpsInt(data, s -> s.map(mDoubler), s -> s.map(e -> 2*e), s -> s.map(e -> 2*e), s -> s.map(e -> 2*e));
exerciseOpsInt(data, s -> s.map(LambdaTestHelpers.compose(mId, mDoubler)), s -> s.map(e -> 2*e), s -> s.map(e -> 2*e), s -> s.map(e -> 2*e));
exerciseOpsInt(data, s -> s.map(LambdaTestHelpers.compose(mDoubler, mDoubler)), s -> s.map(e -> 4*e), s -> s.map(e -> 4*e), s -> s.map(e -> 4*e));
exerciseOps(data, s -> s.mapToInt(i -> i));
exerciseOps(data, s -> s.mapToLong(i -> i));
exerciseOps(data, s -> s.mapToDouble(i -> i));
}
//
@Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
public void testIntOps(String name, TestData.OfInt data) {
exerciseOps(data, s -> s.mapToObj(i -> i));
exerciseOps(data, s -> s.map(i -> 0));
exerciseOps(data, s -> s.map(i -> i * 2));
exerciseOps(data, s -> s.asLongStream());
exerciseOps(data, s -> s.asDoubleStream());
exerciseOps(data, s -> s.boxed());
exerciseOps(data, s -> s.mapToObj(Integer::toString));
exerciseOps(data, s -> s.mapToLong(i -> i));
exerciseOps(data, s -> s.mapToDouble(i -> i));
}
//
@Test(dataProvider = "LongStreamTestData", dataProviderClass = LongStreamTestDataProvider.class)
public void testLongOps(String name, TestData.OfLong data) {
exerciseOps(data, s -> s.mapToObj(i -> i));
exerciseOps(data, s -> s.map(i -> 0L));
exerciseOps(data, s -> s.map(i -> i * 2L));
exerciseOps(data, s -> s.asDoubleStream());
exerciseOps(data, s -> s.boxed());
exerciseOps(data, s -> s.mapToObj(e -> Long.toString(e)));
exerciseOps(data, s -> s.mapToInt(i -> (int) i));
exerciseOps(data, s -> s.mapToDouble(i -> i));
}
//
@Test(dataProvider = "DoubleStreamTestData", dataProviderClass = DoubleStreamTestDataProvider.class)
public void testDoubleOps(String name, TestData.OfDouble data) {
exerciseOps(data, s -> s.mapToObj(i -> i));
exerciseOps(data, s -> s.map(i -> 0.0));
exerciseOps(data, s -> s.map(i -> i * 2.0));
exerciseOps(data, s -> s.boxed());
exerciseOps(data, s -> s.mapToObj(e -> Double.toString(e)));
exerciseOps(data, s -> s.mapToLong(i -> (long) i));
exerciseOps(data, s -> s.mapToInt(i -> (int) i));
}
}

View file

@ -0,0 +1,422 @@
/*
* Copyright (c) 2012, 2013, 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.
*/
package org.openjdk.tests.java.util.stream;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.PrimitiveIterator;
import java.util.Spliterators;
import java.util.function.DoublePredicate;
import java.util.function.Function;
import java.util.function.IntPredicate;
import java.util.function.LongPredicate;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.stream.DoubleStream;
import java.util.stream.DoubleStreamTestDataProvider;
import java.util.stream.IntStream;
import java.util.stream.IntStreamTestDataProvider;
import java.util.stream.LongStream;
import java.util.stream.LongStreamTestDataProvider;
import java.util.stream.OpTestCase;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
import java.util.stream.StreamTestDataProvider;
import java.util.stream.TestData;
import org.testng.annotations.Test;
import static java.util.stream.LambdaTestHelpers.countTo;
import static java.util.stream.LambdaTestHelpers.dpEven;
import static java.util.stream.LambdaTestHelpers.dpFalse;
import static java.util.stream.LambdaTestHelpers.dpOdd;
import static java.util.stream.LambdaTestHelpers.dpTrue;
import static java.util.stream.LambdaTestHelpers.ipEven;
import static java.util.stream.LambdaTestHelpers.ipFalse;
import static java.util.stream.LambdaTestHelpers.ipOdd;
import static java.util.stream.LambdaTestHelpers.ipTrue;
import static java.util.stream.LambdaTestHelpers.lpEven;
import static java.util.stream.LambdaTestHelpers.lpFalse;
import static java.util.stream.LambdaTestHelpers.lpOdd;
import static java.util.stream.LambdaTestHelpers.lpTrue;
import static java.util.stream.LambdaTestHelpers.pEven;
import static java.util.stream.LambdaTestHelpers.pFalse;
import static java.util.stream.LambdaTestHelpers.pOdd;
import static java.util.stream.LambdaTestHelpers.pTrue;
/**
* MatchOpTest
*
* @author Brian Goetz
*/
@Test
public class MatchOpTest extends OpTestCase {
private enum Kind { ANY, ALL, NONE }
@SuppressWarnings("unchecked")
private static final Predicate<Integer>[] INTEGER_PREDICATES
= (Predicate<Integer>[]) new Predicate<?>[]{pTrue, pFalse, pEven, pOdd};
@SuppressWarnings({"serial", "rawtypes"})
private final Map kinds
= new HashMap<Kind, Function<Predicate<Integer>, Function<Stream<Integer>, Boolean>>>() {{
put(Kind.ANY, p -> s -> s.anyMatch(p));
put(Kind.ALL, p -> s -> s.allMatch(p));
put(Kind.NONE, p -> s -> s.noneMatch(p));
}};
@SuppressWarnings("unchecked")
private <T> Map<Kind, Function<Predicate<T>, Function<Stream<T>, Boolean>>> kinds() {
return (Map<Kind, Function<Predicate<T>, Function<Stream<T>, Boolean>>>) kinds;
}
private <T> void assertPredicates(List<T> source, Kind kind, Predicate<T>[] predicates, boolean... answers) {
for (int i = 0; i < predicates.length; i++) {
setContext("i", i);
boolean match = this.<T>kinds().get(kind).apply(predicates[i]).apply(source.stream());
assertEquals(answers[i], match, kind.toString() + predicates[i].toString());
}
}
public void testStreamMatches() {
assertPredicates(countTo(0), Kind.ANY, INTEGER_PREDICATES, false, false, false, false);
assertPredicates(countTo(0), Kind.ALL, INTEGER_PREDICATES, true, true, true, true);
assertPredicates(countTo(0), Kind.NONE, INTEGER_PREDICATES, true, true, true, true);
assertPredicates(countTo(1), Kind.ANY, INTEGER_PREDICATES, true, false, false, true);
assertPredicates(countTo(1), Kind.ALL, INTEGER_PREDICATES, true, false, false, true);
assertPredicates(countTo(1), Kind.NONE, INTEGER_PREDICATES, false, true, true, false);
assertPredicates(countTo(5), Kind.ANY, INTEGER_PREDICATES, true, false, true, true);
assertPredicates(countTo(5), Kind.ALL, INTEGER_PREDICATES, true, false, false, false);
assertPredicates(countTo(5), Kind.NONE, INTEGER_PREDICATES, false, true, false, false);
}
@Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
public void testStream(String name, TestData.OfRef<Integer> data) {
for (Predicate<Integer> p : INTEGER_PREDICATES) {
setContext("p", p);
for (Kind kind : Kind.values()) {
setContext("kind", kind);
exerciseTerminalOps(data, this.<Integer>kinds().get(kind).apply(p));
exerciseTerminalOps(data, s -> s.filter(pFalse), this.<Integer>kinds().get(kind).apply(p));
exerciseTerminalOps(data, s -> s.filter(pEven), this.<Integer>kinds().get(kind).apply(p));
}
}
}
public void testInfinite() {
class CycleIterator implements Iterator<Integer> {
final Supplier<Iterator<Integer>> source;
Iterator<Integer> i = null;
CycleIterator(Supplier<Iterator<Integer>> source) {
this.source = source;
}
@Override
public Integer next() {
if (i == null || !i.hasNext()) {
i = source.get();
}
return i.next();
}
@Override
public boolean hasNext() {
if (i == null || !i.hasNext()) {
i = source.get();
}
return i.hasNext();
}
}
Supplier<Iterator<Integer>> source = () -> Arrays.asList(1, 2, 3, 4).iterator();
Supplier<Stream<Integer>> s = () -> StreamSupport.stream(Spliterators.spliteratorUnknownSize(new CycleIterator(source), 0), false);
assertFalse(s.get().allMatch(i -> i > 3));
assertTrue(s.get().anyMatch(i -> i > 3));
assertFalse(s.get().noneMatch(i -> i > 3));
assertFalse(s.get().parallel().allMatch(i -> i > 3));
assertTrue(s.get().parallel().anyMatch(i -> i > 3));
assertFalse(s.get().parallel().noneMatch(i -> i > 3));
}
//
private static final IntPredicate[] INT_PREDICATES
= new IntPredicate[]{ipTrue, ipFalse, ipEven, ipOdd};
@SuppressWarnings("serial")
private final Map<Kind, Function<IntPredicate, Function<IntStream, Boolean>>> intKinds
= new HashMap<Kind, Function<IntPredicate, Function<IntStream, Boolean>>>() {{
put(Kind.ANY, p -> s -> s.anyMatch(p));
put(Kind.ALL, p -> s -> s.allMatch(p));
put(Kind.NONE, p -> s -> s.noneMatch(p));
}};
private void assertIntPredicates(Supplier<IntStream> source, Kind kind, IntPredicate[] predicates, boolean... answers) {
for (int i = 0; i < predicates.length; i++) {
setContext("i", i);
boolean match = intKinds.get(kind).apply(predicates[i]).apply(source.get());
assertEquals(answers[i], match, kind.toString() + predicates[i].toString());
}
}
public void testIntStreamMatches() {
assertIntPredicates(() -> IntStream.range(0, 0), Kind.ANY, INT_PREDICATES, false, false, false, false);
assertIntPredicates(() -> IntStream.range(0, 0), Kind.ALL, INT_PREDICATES, true, true, true, true);
assertIntPredicates(() -> IntStream.range(0, 0), Kind.NONE, INT_PREDICATES, true, true, true, true);
assertIntPredicates(() -> IntStream.range(1, 2), Kind.ANY, INT_PREDICATES, true, false, false, true);
assertIntPredicates(() -> IntStream.range(1, 2), Kind.ALL, INT_PREDICATES, true, false, false, true);
assertIntPredicates(() -> IntStream.range(1, 2), Kind.NONE, INT_PREDICATES, false, true, true, false);
assertIntPredicates(() -> IntStream.range(1, 6), Kind.ANY, INT_PREDICATES, true, false, true, true);
assertIntPredicates(() -> IntStream.range(1, 6), Kind.ALL, INT_PREDICATES, true, false, false, false);
assertIntPredicates(() -> IntStream.range(1, 6), Kind.NONE, INT_PREDICATES, false, true, false, false);
}
@Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
public void testIntStream(String name, TestData.OfInt data) {
for (IntPredicate p : INT_PREDICATES) {
setContext("p", p);
for (Kind kind : Kind.values()) {
setContext("kind", kind);
exerciseTerminalOps(data, intKinds.get(kind).apply(p));
exerciseTerminalOps(data, s -> s.filter(ipFalse), intKinds.get(kind).apply(p));
exerciseTerminalOps(data, s -> s.filter(ipEven), intKinds.get(kind).apply(p));
}
}
}
public void testIntInfinite() {
class CycleIterator implements PrimitiveIterator.OfInt {
final Supplier<PrimitiveIterator.OfInt> source;
PrimitiveIterator.OfInt i = null;
CycleIterator(Supplier<PrimitiveIterator.OfInt> source) {
this.source = source;
}
@Override
public int nextInt() {
if (i == null || !i.hasNext()) {
i = source.get();
}
return i.nextInt();
}
@Override
public boolean hasNext() {
if (i == null || !i.hasNext()) {
i = source.get();
}
return i.hasNext();
}
}
Supplier<PrimitiveIterator.OfInt> source = () -> Arrays.stream(new int[]{1, 2, 3, 4}).iterator();
Supplier<IntStream> s = () -> StreamSupport.intStream(Spliterators.spliteratorUnknownSize(new CycleIterator(source), 0), false);
assertFalse(s.get().allMatch(i -> i > 3));
assertTrue(s.get().anyMatch(i -> i > 3));
assertFalse(s.get().noneMatch(i -> i > 3));
assertFalse(s.get().parallel().allMatch(i -> i > 3));
assertTrue(s.get().parallel().anyMatch(i -> i > 3));
assertFalse(s.get().parallel().noneMatch(i -> i > 3));
}
//
private static final LongPredicate[] LONG_PREDICATES
= new LongPredicate[]{lpTrue, lpFalse, lpEven, lpOdd};
@SuppressWarnings("serial")
private final Map<Kind, Function<LongPredicate, Function<LongStream, Boolean>>> longKinds
= new HashMap<Kind, Function<LongPredicate, Function<LongStream, Boolean>>>() {{
put(Kind.ANY, p -> s -> s.anyMatch(p));
put(Kind.ALL, p -> s -> s.allMatch(p));
put(Kind.NONE, p -> s -> s.noneMatch(p));
}};
private void assertLongPredicates(Supplier<LongStream> source, Kind kind, LongPredicate[] predicates, boolean... answers) {
for (int i = 0; i < predicates.length; i++) {
setContext("i", i);
boolean match = longKinds.get(kind).apply(predicates[i]).apply(source.get());
assertEquals(answers[i], match, kind.toString() + predicates[i].toString());
}
}
public void testLongStreamMatches() {
assertLongPredicates(() -> LongStream.range(0, 0), Kind.ANY, LONG_PREDICATES, false, false, false, false);
assertLongPredicates(() -> LongStream.range(0, 0), Kind.ALL, LONG_PREDICATES, true, true, true, true);
assertLongPredicates(() -> LongStream.range(0, 0), Kind.NONE, LONG_PREDICATES, true, true, true, true);
assertLongPredicates(() -> LongStream.range(1, 2), Kind.ANY, LONG_PREDICATES, true, false, false, true);
assertLongPredicates(() -> LongStream.range(1, 2), Kind.ALL, LONG_PREDICATES, true, false, false, true);
assertLongPredicates(() -> LongStream.range(1, 2), Kind.NONE, LONG_PREDICATES, false, true, true, false);
assertLongPredicates(() -> LongStream.range(1, 6), Kind.ANY, LONG_PREDICATES, true, false, true, true);
assertLongPredicates(() -> LongStream.range(1, 6), Kind.ALL, LONG_PREDICATES, true, false, false, false);
assertLongPredicates(() -> LongStream.range(1, 6), Kind.NONE, LONG_PREDICATES, false, true, false, false);
}
@Test(dataProvider = "LongStreamTestData", dataProviderClass = LongStreamTestDataProvider.class)
public void testLongStream(String name, TestData.OfLong data) {
for (LongPredicate p : LONG_PREDICATES) {
setContext("p", p);
for (Kind kind : Kind.values()) {
setContext("kind", kind);
exerciseTerminalOps(data, longKinds.get(kind).apply(p));
exerciseTerminalOps(data, s -> s.filter(lpFalse), longKinds.get(kind).apply(p));
exerciseTerminalOps(data, s -> s.filter(lpEven), longKinds.get(kind).apply(p));
}
}
}
public void testLongInfinite() {
class CycleIterator implements PrimitiveIterator.OfLong {
final Supplier<PrimitiveIterator.OfLong> source;
PrimitiveIterator.OfLong i = null;
CycleIterator(Supplier<PrimitiveIterator.OfLong> source) {
this.source = source;
}
@Override
public long nextLong() {
if (i == null || !i.hasNext()) {
i = source.get();
}
return i.nextLong();
}
@Override
public boolean hasNext() {
if (i == null || !i.hasNext()) {
i = source.get();
}
return i.hasNext();
}
}
Supplier<PrimitiveIterator.OfLong> source = () -> Arrays.stream(new long[]{1, 2, 3, 4}).iterator();
Supplier<LongStream> s = () -> StreamSupport.longStream(Spliterators.spliteratorUnknownSize(new CycleIterator(source), 0), false);
assertFalse(s.get().allMatch(i -> i > 3));
assertTrue(s.get().anyMatch(i -> i > 3));
assertFalse(s.get().noneMatch(i -> i > 3));
assertFalse(s.get().parallel().allMatch(i -> i > 3));
assertTrue(s.get().parallel().anyMatch(i -> i > 3));
assertFalse(s.get().parallel().noneMatch(i -> i > 3));
}
//
private static final DoublePredicate[] DOUBLE_PREDICATES
= new DoublePredicate[]{dpTrue, dpFalse, dpEven, dpOdd};
@SuppressWarnings("serial")
private final Map<Kind, Function<DoublePredicate, Function<DoubleStream, Boolean>>> doubleKinds
= new HashMap<Kind, Function<DoublePredicate, Function<DoubleStream, Boolean>>>() {{
put(Kind.ANY, p -> s -> s.anyMatch(p));
put(Kind.ALL, p -> s -> s.allMatch(p));
put(Kind.NONE, p -> s -> s.noneMatch(p));
}};
private void assertDoublePredicates(Supplier<DoubleStream> source, Kind kind, DoublePredicate[] predicates, boolean... answers) {
for (int i = 0; i < predicates.length; i++) {
setContext("i", i);
boolean match = doubleKinds.get(kind).apply(predicates[i]).apply(source.get());
assertEquals(answers[i], match, kind.toString() + predicates[i].toString());
}
}
public void testDoubleStreamMatches() {
assertDoublePredicates(() -> LongStream.range(0, 0).asDoubleStream(), Kind.ANY, DOUBLE_PREDICATES, false, false, false, false);
assertDoublePredicates(() -> LongStream.range(0, 0).asDoubleStream(), Kind.ALL, DOUBLE_PREDICATES, true, true, true, true);
assertDoublePredicates(() -> LongStream.range(0, 0).asDoubleStream(), Kind.NONE, DOUBLE_PREDICATES, true, true, true, true);
assertDoublePredicates(() -> LongStream.range(1, 2).asDoubleStream(), Kind.ANY, DOUBLE_PREDICATES, true, false, false, true);
assertDoublePredicates(() -> LongStream.range(1, 2).asDoubleStream(), Kind.ALL, DOUBLE_PREDICATES, true, false, false, true);
assertDoublePredicates(() -> LongStream.range(1, 2).asDoubleStream(), Kind.NONE, DOUBLE_PREDICATES, false, true, true, false);
assertDoublePredicates(() -> LongStream.range(1, 6).asDoubleStream(), Kind.ANY, DOUBLE_PREDICATES, true, false, true, true);
assertDoublePredicates(() -> LongStream.range(1, 6).asDoubleStream(), Kind.ALL, DOUBLE_PREDICATES, true, false, false, false);
assertDoublePredicates(() -> LongStream.range(1, 6).asDoubleStream(), Kind.NONE, DOUBLE_PREDICATES, false, true, false, false);
}
@Test(dataProvider = "DoubleStreamTestData", dataProviderClass = DoubleStreamTestDataProvider.class)
public void testDoubleStream(String name, TestData.OfDouble data) {
for (DoublePredicate p : DOUBLE_PREDICATES) {
setContext("p", p);
for (Kind kind : Kind.values()) {
setContext("kind", kind);
exerciseTerminalOps(data, doubleKinds.get(kind).apply(p));
exerciseTerminalOps(data, s -> s.filter(dpFalse), doubleKinds.get(kind).apply(p));
exerciseTerminalOps(data, s -> s.filter(dpEven), doubleKinds.get(kind).apply(p));
}
}
}
public void testDoubleInfinite() {
class CycleIterator implements PrimitiveIterator.OfDouble {
final Supplier<PrimitiveIterator.OfDouble> source;
PrimitiveIterator.OfDouble i = null;
CycleIterator(Supplier<PrimitiveIterator.OfDouble> source) {
this.source = source;
}
@Override
public double nextDouble() {
if (i == null || !i.hasNext()) {
i = source.get();
}
return i.nextDouble();
}
@Override
public boolean hasNext() {
if (i == null || !i.hasNext()) {
i = source.get();
}
return i.hasNext();
}
}
Supplier<PrimitiveIterator.OfDouble> source = () -> Arrays.stream(new double[]{1, 2, 3, 4}).iterator();
Supplier<DoubleStream> s = () -> StreamSupport.doubleStream(Spliterators.spliteratorUnknownSize(new CycleIterator(source), 0), false);
assertFalse(s.get().allMatch(i -> i > 3));
assertTrue(s.get().anyMatch(i -> i > 3));
assertFalse(s.get().noneMatch(i -> i > 3));
assertFalse(s.get().parallel().allMatch(i -> i > 3));
assertTrue(s.get().parallel().anyMatch(i -> i > 3));
assertFalse(s.get().parallel().noneMatch(i -> i > 3));
}
}

View file

@ -0,0 +1,92 @@
/*
* Copyright (c) 2012, 2013, 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.
*/
package org.openjdk.tests.java.util.stream;
import java.util.OptionalDouble;
import java.util.OptionalInt;
import java.util.OptionalLong;
import java.util.stream.*;
import org.testng.annotations.Test;
import static java.util.stream.LambdaTestHelpers.countTo;
/**
* MinMaxTest
*
* @author Brian Goetz
*/
@Test
public class MinMaxTest extends OpTestCase {
public void testMinMax() {
assertTrue(!countTo(0).stream().min(Integer::compare).isPresent());
assertTrue(!countTo(0).stream().max(Integer::compare).isPresent());
assertEquals(1, (int) countTo(1000).stream().min(Integer::compare).get());
assertEquals(1000, (int) countTo(1000).stream().max(Integer::compare).get());
}
@Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
public void testOps(String name, TestData.OfRef<Integer> data) {
exerciseTerminalOps(data, s -> s.min(Integer::compare));
exerciseTerminalOps(data, s -> s.max(Integer::compare));
}
public void testIntMinMax() {
assertEquals(IntStream.empty().min(), OptionalInt.empty());
assertEquals(IntStream.empty().max(), OptionalInt.empty());
assertEquals(1, IntStream.range(1, 1001).min().getAsInt());
assertEquals(1000, IntStream.range(1, 1001).max().getAsInt());
}
@Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
public void testIntOps(String name, TestData.OfInt data) {
exerciseTerminalOps(data, s -> s.min());
exerciseTerminalOps(data, s -> s.max());
}
public void testLongMinMax() {
assertEquals(LongStream.empty().min(), OptionalLong.empty());
assertEquals(LongStream.empty().max(), OptionalLong.empty());
assertEquals(1, LongStream.range(1, 1001).min().getAsLong());
assertEquals(1000, LongStream.range(1, 1001).max().getAsLong());
}
@Test(dataProvider = "LongStreamTestData", dataProviderClass = LongStreamTestDataProvider.class)
public void testLongOps(String name, TestData.OfLong data) {
exerciseTerminalOps(data, s -> s.min());
exerciseTerminalOps(data, s -> s.max());
}
public void testDoubleMinMax() {
assertEquals(DoubleStream.empty().min(), OptionalDouble.empty());
assertEquals(DoubleStream.empty().max(), OptionalDouble.empty());
assertEquals(1.0, LongStream.range(1, 1001).asDoubleStream().min().getAsDouble());
assertEquals(1000.0, LongStream.range(1, 1001).asDoubleStream().max().getAsDouble());
}
@Test(dataProvider = "DoubleStreamTestData", dataProviderClass = DoubleStreamTestDataProvider.class)
public void testDoubleOps(String name, TestData.OfDouble data) {
exerciseTerminalOps(data, s -> s.min());
exerciseTerminalOps(data, s -> s.max());
}
}

View file

@ -0,0 +1,50 @@
/*
* Copyright (c) 2012, 2013, 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.
*/
package org.openjdk.tests.java.util.stream;
import java.util.stream.*;
import org.testng.annotations.Test;
public class PrimitiveAverageOpTest extends OpTestCase {
@Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
public void testOps(String name, TestData.OfInt data) {
exerciseTerminalOps(data, s -> s.average());
}
@Test(dataProvider = "LongStreamTestData", dataProviderClass = LongStreamTestDataProvider.class)
public void testOps(String name, TestData.OfLong data) {
exerciseTerminalOps(data, s -> s.average());
}
// @@@ For Double depending on the input data the average algorithm may produce slightly
// different results for the sequential and parallel evaluation.results are within
// While the following works at the moment, it could change when double data, not cast from long
// values is introduced, or if the average/sum algorithm is modified.
@Test(dataProvider = "DoubleStreamTestData", dataProviderClass = DoubleStreamTestDataProvider.class)
public void testOps(String name, TestData.OfDouble data) {
exerciseTerminalOps(data, s -> s.average());
}
}

View file

@ -0,0 +1,65 @@
/*
* Copyright (c) 2012, 2013, 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.
*/
package org.openjdk.tests.java.util.stream;
import java.util.stream.*;
import org.testng.annotations.Test;
public class PrimitiveSumTest extends OpTestCase {
@Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
public void testOps(String name, TestData.OfInt data) {
exerciseTerminalOps(data, s -> s.sum());
withData(data).
terminal(s -> (long) s.sum()).
expectedResult(data.stream().asLongStream().reduce(0, LambdaTestHelpers.lrPlus)).
exercise();
}
@Test(dataProvider = "LongStreamTestData", dataProviderClass = LongStreamTestDataProvider.class)
public void testOps(String name, TestData.OfLong data) {
exerciseTerminalOps(data, s -> s.sum());
withData(data).
terminal(s -> s.sum()).
expectedResult(data.stream().reduce(0, LambdaTestHelpers.lrPlus)).
exercise();
}
// @@@ For Double depending on the input data the average algorithm may produce slightly
// different results for the sequential and parallel evaluation.results are within
// While the following works at the moment, it could change when double data, not cast from long
// values is introduced, or if the sum algorithm is modified.
@Test(dataProvider = "DoubleStreamTestData", dataProviderClass = DoubleStreamTestDataProvider.class)
public void testOps(String name, TestData.OfDouble data) {
exerciseTerminalOps(data, s -> s.sum());
withData(data).
terminal(s -> s.sum()).
expectedResult(data.stream().reduce(0, LambdaTestHelpers.drPlus)).
exercise();
}
}

View file

@ -0,0 +1,339 @@
/*
* Copyright (c) 2012, 2017, 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.
*/
package org.openjdk.tests.java.util.stream;
import java.util.Arrays;
import java.util.Optional;
import java.util.Spliterator;
import java.util.SpliteratorTestHelper;
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 org.testng.annotations.Test;
/**
* Primitive range tests
*
* @author Brian Goetz
*/
@Test
public class RangeTest extends OpTestCase {
public void testInfiniteRangeFindFirst() {
Integer first = Stream.iterate(0, i -> i + 1).filter(i -> i > 10000).findFirst().get();
assertEquals(first, Stream.iterate(0, i -> i + 1).parallel().filter(i -> i > 10000).findFirst().get());
// Limit is required to transform the infinite stream to a finite stream
// since the exercising requires a finite stream
withData(TestData.Factory.ofSupplier(
"", () -> Stream.iterate(0, i -> i + 1).filter(i -> i > 10000).limit(20000))).
terminal(s->s.findFirst()).expectedResult(Optional.of(10001)).exercise();
}
//
public void testIntRange() {
// Half-open
for (int start : Arrays.asList(1, 10, -1, -10)) {
setContext("start", start);
for (int end : Arrays.asList(1, 10, -1, -10)) {
setContext("end", end);
int size = (start < end) ? end - start : 0;
int[] exp = new int[size];
for (int i = start, p = 0; i < end; i++, p++) {
exp[p] = i;
}
int[] inc = IntStream.range(start, end).toArray();
assertEquals(inc.length, size);
assertTrue(Arrays.equals(exp, inc));
withData(intRangeData(start, end)).stream(s -> s).
expectedResult(exp).exercise();
}
}
// Closed
for (int start : Arrays.asList(1, 10, -1, -10)) {
setContext("start", start);
for (int end : Arrays.asList(1, 10, -1, -10)) {
setContext("end", end);
int size = (start <= end) ? end - start + 1 : 0;
int[] exp = new int[size];
for (int i = start, p = 0; i <= end; i++, p++) {
exp[p] = i;
}
int[] inc = IntStream.rangeClosed(start, end).toArray();
assertEquals(inc.length, size);
assertTrue(Arrays.equals(exp, inc));
withData(intRangeClosedData(start, end)).stream(s -> s).
expectedResult(exp).exercise();
}
}
// Closed, maximum upper bound of Integer.MAX_VALUE
{
int[] inc = IntStream.rangeClosed(Integer.MAX_VALUE - 1, Integer.MAX_VALUE).toArray();
assertEquals(2, inc.length);
assertEquals(Integer.MAX_VALUE - 1, inc[0]);
assertEquals(Integer.MAX_VALUE, inc[1]);
inc = IntStream.rangeClosed(Integer.MAX_VALUE, Integer.MAX_VALUE).toArray();
assertEquals(1, inc.length);
assertEquals(Integer.MAX_VALUE, inc[0]);
SpliteratorTestHelper.testIntSpliterator(
() -> IntStream.rangeClosed(Integer.MAX_VALUE - 8, Integer.MAX_VALUE).spliterator());
}
// Range wider than Integer.MAX_VALUE
{
Spliterator.OfInt s = IntStream.rangeClosed(Integer.MIN_VALUE, Integer.MAX_VALUE).
spliterator();
assertEquals(s.estimateSize(), 1L << 32);
}
}
TestData.OfInt intRangeData(int start, int end) {
return TestData.Factory.ofIntSupplier("int range", () -> IntStream.range(start, end));
}
TestData.OfInt intRangeClosedData(int start, int end) {
return TestData.Factory.ofIntSupplier("int rangeClosed", () -> IntStream.rangeClosed(start, end));
}
public void tesIntRangeReduce() {
withData(intRangeData(0, 10000)).
terminal(s -> s.reduce(0, Integer::sum)).exercise();
}
public void testIntInfiniteRangeLimit() {
withData(TestData.Factory.ofIntSupplier(
"int range", () -> IntStream.iterate(0, i -> i + 1).limit(10000))).
terminal(s -> s.reduce(0, Integer::sum)).exercise();
}
public void testIntInfiniteRangeFindFirst() {
int first = IntStream.iterate(0, i -> i + 1).filter(i -> i > 10000).findFirst().getAsInt();
assertEquals(first, IntStream.iterate(0, i -> i + 1).parallel().filter(i -> i > 10000).findFirst().getAsInt());
}
//
public void testLongRange() {
// Half-open
for (long start : Arrays.asList(1, 1000, -1, -1000)) {
setContext("start", start);
for (long end : Arrays.asList(1, 1000, -1, -1000)) {
setContext("end", end);
long size = start < end ? end - start : 0;
long[] exp = new long[(int) size];
for (long i = start, p = 0; i < end; i++, p++) {
exp[(int) p] = i;
}
long[] inc = LongStream.range(start, end).toArray();
assertEquals(inc.length, size);
assertTrue(Arrays.equals(exp, inc));
withData(longRangeData(start, end)).stream(s -> s).
expectedResult(exp).exercise();
}
}
// Closed
for (long start : Arrays.asList(1, 1000, -1, -1000)) {
setContext("start", start);
for (long end : Arrays.asList(1, 1000, -1, -1000)) {
setContext("end", end);
long size = start <= end ? end - start + 1: 0;
long[] exp = new long[(int) size];
for (long i = start, p = 0; i <= end; i++, p++) {
exp[(int) p] = i;
}
long[] inc = LongStream.rangeClosed(start, end).toArray();
assertEquals(inc.length, size);
assertTrue(Arrays.equals(exp, inc));
withData(longRangeClosedData(start, end)).stream(s -> s).
expectedResult(exp).exercise();
}
}
// Closed, maximum upper bound of Long.MAX_VALUE
{
long[] inc = LongStream.rangeClosed(Long.MAX_VALUE - 1, Long.MAX_VALUE).toArray();
assertEquals(2, inc.length);
assertEquals(Long.MAX_VALUE - 1, inc[0]);
assertEquals(Long.MAX_VALUE, inc[1]);
inc = LongStream.rangeClosed(Long.MAX_VALUE, Long.MAX_VALUE).toArray();
assertEquals(1, inc.length);
assertEquals(Long.MAX_VALUE, inc[0]);
SpliteratorTestHelper.testLongSpliterator(
() -> LongStream.rangeClosed(Long.MAX_VALUE - 8, Long.MAX_VALUE).spliterator());
}
}
TestData.OfLong longRangeData(long start, long end) {
return TestData.Factory.ofLongSupplier("long range", () -> LongStream.range(start, end));
}
TestData.OfLong longRangeClosedData(long start, long end) {
return TestData.Factory.ofLongSupplier("long rangeClosed", () -> LongStream.rangeClosed(start, end));
}
public void testLongRangeReduce() {
withData(longRangeData(0, 10000)).
terminal(s -> s.reduce(0, Long::sum)).exercise();
}
public void testLongInfiniteRangeLimit() {
withData(TestData.Factory.ofLongSupplier(
"long range", () -> LongStream.iterate(0, i -> i + 1).limit(10000))).
terminal(s -> s.reduce(0, Long::sum)).exercise();
}
public void testLongInfiniteRangeFindFirst() {
long first = LongStream.iterate(0, i -> i + 1).filter(i -> i > 10000).findFirst().getAsLong();
assertEquals(first, LongStream.iterate(0, i -> i + 1).parallel().filter(i -> i > 10000).findFirst().getAsLong());
}
private static void assertSizedAndSubSized(Spliterator<?> s) {
assertTrue(s.hasCharacteristics(Spliterator.SIZED | Spliterator.SUBSIZED));
}
private static void assertNotSizedAndSubSized(Spliterator<?> s) {
assertFalse(s.hasCharacteristics(Spliterator.SIZED | Spliterator.SUBSIZED));
}
public void testLongLongRange() {
// Test [Long.MIN_VALUE, Long.MAX_VALUE)
// This will concatenate streams of three ranges
// [Long.MIN_VALUE, x) [x, 0) [0, Long.MAX_VALUE)
// where x = Long.divideUnsigned(0 - Long.MIN_VALUE, 2) + 1
{
Spliterator.OfLong s = LongStream.range(Long.MIN_VALUE, Long.MAX_VALUE).spliterator();
assertEquals(s.estimateSize(), Long.MAX_VALUE);
assertNotSizedAndSubSized(s);
Spliterator.OfLong s1 = s.trySplit();
assertNotSizedAndSubSized(s1);
assertSizedAndSubSized(s);
Spliterator.OfLong s2 = s1.trySplit();
assertSizedAndSubSized(s1);
assertSizedAndSubSized(s2);
assertTrue(s.estimateSize() == Long.MAX_VALUE);
assertTrue(s1.estimateSize() < Long.MAX_VALUE);
assertTrue(s2.estimateSize() < Long.MAX_VALUE);
assertEquals(s.estimateSize() + s1.estimateSize() + s2.estimateSize(),
Long.MAX_VALUE - Long.MIN_VALUE);
}
long[][] ranges = { {Long.MIN_VALUE, 0}, {-1, Long.MAX_VALUE} };
for (int i = 0; i < ranges.length; i++) {
long start = ranges[i][0];
long end = ranges[i][1];
Spliterator.OfLong s = LongStream.range(start, end).spliterator();
assertEquals(s.estimateSize(), Long.MAX_VALUE);
assertNotSizedAndSubSized(s);
Spliterator.OfLong s1 = s.trySplit();
assertSizedAndSubSized(s1);
assertSizedAndSubSized(s);
assertTrue(s.estimateSize() < Long.MAX_VALUE);
assertTrue(s1.estimateSize() < Long.MAX_VALUE);
assertEquals(s.estimateSize() + s1.estimateSize(), end - start);
}
}
public void testLongLongRangeClosed() {
// Test [Long.MIN_VALUE, Long.MAX_VALUE]
// This will concatenate streams of four ranges
// [Long.MIN_VALUE, x) [x, 0) [0, y) [y, Long.MAX_VALUE]
// where x = Long.divideUnsigned(0 - Long.MIN_VALUE, 2) + 1
// y = Long.divideUnsigned(Long.MAX_VALUE, 2) + 1
{
Spliterator.OfLong s = LongStream.rangeClosed(Long.MIN_VALUE, Long.MAX_VALUE).spliterator();
assertEquals(s.estimateSize(), Long.MAX_VALUE);
assertNotSizedAndSubSized(s);
Spliterator.OfLong s1 = s.trySplit();
assertNotSizedAndSubSized(s1);
assertNotSizedAndSubSized(s);
Spliterator.OfLong s2 = s1.trySplit();
assertSizedAndSubSized(s1);
assertSizedAndSubSized(s2);
Spliterator.OfLong s3 = s.trySplit();
assertSizedAndSubSized(s3);
assertSizedAndSubSized(s);
assertTrue(s.estimateSize() < Long.MAX_VALUE);
assertTrue(s3.estimateSize() < Long.MAX_VALUE);
assertTrue(s1.estimateSize() < Long.MAX_VALUE);
assertTrue(s2.estimateSize() < Long.MAX_VALUE);
assertEquals(s.estimateSize() + s3.estimateSize() + s1.estimateSize() + s2.estimateSize(),
Long.MAX_VALUE - Long.MIN_VALUE + 1);
}
long[][] ranges = { {Long.MIN_VALUE, 0}, {-1, Long.MAX_VALUE} };
for (int i = 0; i < ranges.length; i++) {
long start = ranges[i][0];
long end = ranges[i][1];
Spliterator.OfLong s = LongStream.rangeClosed(start, end).spliterator();
assertEquals(s.estimateSize(), Long.MAX_VALUE);
assertNotSizedAndSubSized(s);
Spliterator.OfLong s1 = s.trySplit();
assertSizedAndSubSized(s1);
assertSizedAndSubSized(s);
assertTrue(s.estimateSize() < Long.MAX_VALUE);
assertTrue(s1.estimateSize() < Long.MAX_VALUE);
assertEquals(s.estimateSize() + s1.estimateSize(), end - start + 1);
}
}
}

View file

@ -0,0 +1,68 @@
/*
* Copyright (c) 2012, 2013, 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.
*/
package org.openjdk.tests.java.util.stream;
import java.util.List;
import java.util.stream.LambdaTestHelpers;
import java.util.stream.OpTestCase;
import java.util.stream.Stream;
import java.util.stream.StreamTestDataProvider;
import org.testng.annotations.Test;
import java.util.HashSet;
import java.util.Map;
import java.util.stream.TestData;
import static java.util.stream.Collectors.groupingBy;
import static java.util.stream.Collectors.reducing;
import static java.util.stream.LambdaTestHelpers.*;
/**
* ReduceByOpTest
*
* @author Brian Goetz
*/
@Test
public class ReduceByOpTest extends OpTestCase {
@Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
public void testOps(String name, TestData.OfRef<Integer> data) {
Map<Boolean,List<Integer>> gbResult = data.stream().collect(groupingBy(LambdaTestHelpers.forPredicate(pEven, true, false)));
Map<Boolean, Integer> result = data.stream().collect(groupingBy(LambdaTestHelpers.forPredicate(pEven, true, false), reducing(0, rPlus)));
assertEquals(result.size(), gbResult.size());
for (Map.Entry<Boolean, Integer> entry : result.entrySet()) {
setContext("entry", entry);
Boolean key = entry.getKey();
assertEquals(entry.getValue(), data.stream().filter(e -> pEven.test(e) == key).reduce(0, rPlus));
}
int uniqueSize = data.into(new HashSet<Integer>()).size();
Map<Integer, List<Integer>> mgResult = exerciseTerminalOps(data, s -> s.collect(groupingBy(mId)));
Map<Integer, Integer> miResult = exerciseTerminalOps(data, s -> s.collect(groupingBy(mId, reducing(0, e -> 1, Integer::sum))));
assertEquals(miResult.keySet().size(), uniqueSize);
for (Map.Entry<Integer, Integer> entry : miResult.entrySet()) {
setContext("entry", entry);
assertEquals((int) entry.getValue(), mgResult.get(entry.getKey()).size());
}
}
}

View file

@ -0,0 +1,87 @@
/*
* Copyright (c) 2012, 2013, 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.
*/
package org.openjdk.tests.java.util.stream;
import java.util.stream.OpTestCase;
import java.util.stream.Stream;
import java.util.stream.StreamTestDataProvider;
import org.testng.annotations.Test;
import java.util.List;
import java.util.Optional;
import java.util.stream.TestData;
import static java.util.stream.LambdaTestHelpers.*;
/**
* ReduceOpTest
*
* @author Brian Goetz
*/
@Test
public class ReduceTest extends OpTestCase {
public void testReduce() {
List<Integer> list = countTo(10);
assertEquals(55, (int) list.stream().reduce(rPlus).get());
assertEquals(55, (int) list.stream().reduce(0, rPlus));
assertEquals(10, (int) list.stream().reduce(rMax).get());
assertEquals(1, (int) list.stream().reduce(rMin).get());
assertEquals(0, (int) countTo(0).stream().reduce(0, rPlus));
assertTrue(!countTo(0).stream().reduce(rPlus).isPresent());
assertEquals(110, (int) list.stream().map(mDoubler).reduce(rPlus).get());
assertEquals(20, (int) list.stream().map(mDoubler).reduce(rMax).get());
assertEquals(2, (int) list.stream().map(mDoubler).reduce(rMin).get());
}
@Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
public void testOps(String name, TestData.OfRef<Integer> data) {
assertEquals(0, (int) exerciseTerminalOps(data, s -> s.filter(pFalse), s -> s.reduce(0, rPlus, rPlus)));
Optional<Integer> seedless = exerciseTerminalOps(data, s -> s.reduce(rPlus));
Integer folded = exerciseTerminalOps(data, s -> s.reduce(0, rPlus, rPlus));
assertEquals(folded, seedless.orElse(0));
seedless = exerciseTerminalOps(data, s -> s.reduce(rMin));
folded = exerciseTerminalOps(data, s -> s.reduce(Integer.MAX_VALUE, rMin, rMin));
assertEquals(folded, seedless.orElse(Integer.MAX_VALUE));
seedless = exerciseTerminalOps(data, s -> s.reduce(rMax));
folded = exerciseTerminalOps(data, s -> s.reduce(Integer.MIN_VALUE, rMax, rMax));
assertEquals(folded, seedless.orElse(Integer.MIN_VALUE));
seedless = exerciseTerminalOps(data, s -> s.map(mDoubler), s -> s.reduce(rPlus));
folded = exerciseTerminalOps(data, s -> s.map(mDoubler), s -> s.reduce(0, rPlus, rPlus));
assertEquals(folded, seedless.orElse(0));
seedless = exerciseTerminalOps(data, s -> s.map(mDoubler), s -> s.reduce(rMin));
folded = exerciseTerminalOps(data, s -> s.map(mDoubler), s -> s.reduce(Integer.MAX_VALUE, rMin, rMin));
assertEquals(folded, seedless.orElse(Integer.MAX_VALUE));
seedless = exerciseTerminalOps(data, s -> s.map(mDoubler), s -> s.reduce(rMax));
folded = exerciseTerminalOps(data, s -> s.map(mDoubler), s -> s.reduce(Integer.MIN_VALUE, rMax, rMax));
assertEquals(folded, seedless.orElse(Integer.MIN_VALUE));
}
}

View file

@ -0,0 +1,148 @@
/*
* Copyright (c) 2020, 2022, 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.
*/
package org.openjdk.tests.java.util.stream;
import java.lang.foreign.MemoryLayout;
import java.lang.foreign.MemorySegment;
import java.lang.invoke.VarHandle;
import java.util.Collection;
import java.util.List;
import java.util.SpliteratorTestHelper;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.lang.foreign.ValueLayout;
import org.testng.annotations.DataProvider;
public class SegmentTestDataProvider {
static boolean compareSegmentsByte(Collection<MemorySegment> segments1, Collection<MemorySegment> segments2, boolean isOrdered) {
Function<MemorySegment, Byte> mapper = s -> s.get(ValueLayout.JAVA_BYTE, 0);
List<Byte> list1 = segments1.stream()
.map(mapper)
.collect(Collectors.toList());
List<Byte> list2 = segments2.stream()
.map(mapper)
.collect(Collectors.toList());
return list1.equals(list2);
}
static boolean compareSegmentsChar(Collection<MemorySegment> segments1, Collection<MemorySegment> segments2, boolean isOrdered) {
Function<MemorySegment, Character> mapper = s -> s.get(ValueLayout.JAVA_CHAR, 0);
List<Character> list1 = segments1.stream()
.map(mapper)
.collect(Collectors.toList());
List<Character> list2 = segments2.stream()
.map(mapper)
.collect(Collectors.toList());
return list1.equals(list2);
}
static boolean compareSegmentsShort(Collection<MemorySegment> segments1, Collection<MemorySegment> segments2, boolean isOrdered) {
Function<MemorySegment, Short> mapper = s -> s.get(ValueLayout.JAVA_SHORT, 0);
List<Short> list1 = segments1.stream()
.map(mapper)
.collect(Collectors.toList());
List<Short> list2 = segments2.stream()
.map(mapper)
.collect(Collectors.toList());
return list1.equals(list2);
}
static boolean compareSegmentsInt(Collection<MemorySegment> segments1, Collection<MemorySegment> segments2, boolean isOrdered) {
Function<MemorySegment, Integer> mapper = s -> s.get(ValueLayout.JAVA_INT, 0);
List<Integer> list1 = segments1.stream()
.map(mapper)
.collect(Collectors.toList());
List<Integer> list2 = segments2.stream()
.map(mapper)
.collect(Collectors.toList());
return list1.equals(list2);
}
static boolean compareSegmentsLong(Collection<MemorySegment> segments1, Collection<MemorySegment> segments2, boolean isOrdered) {
Function<MemorySegment, Long> mapper = s-> s.get(ValueLayout.JAVA_LONG, 0);
List<Long> list1 = segments1.stream()
.map(mapper)
.collect(Collectors.toList());
List<Long> list2 = segments2.stream()
.map(mapper)
.collect(Collectors.toList());
return list1.equals(list2);
}
static boolean compareSegmentsFloat(Collection<MemorySegment> segments1, Collection<MemorySegment> segments2, boolean isOrdered) {
Function<MemorySegment, Float> mapper = s -> s.get(ValueLayout.JAVA_FLOAT, 0);
List<Float> list1 = segments1.stream()
.map(mapper)
.collect(Collectors.toList());
List<Float> list2 = segments2.stream()
.map(mapper)
.collect(Collectors.toList());
return list1.equals(list2);
}
static Consumer<MemorySegment> segmentCopier(Consumer<MemorySegment> input) {
return segment -> {
MemorySegment dest = MemorySegment.ofArray(new long[(int)segment.byteSize() / 8]);
dest.copyFrom(segment);
input.accept(dest);
};
}
static boolean compareSegmentsDouble(Collection<MemorySegment> segments1, Collection<MemorySegment> segments2, boolean isOrdered) {
Function<MemorySegment, Double> mapper = s -> s.get(ValueLayout.JAVA_DOUBLE, 0);
List<Double> list1 = segments1.stream()
.map(mapper)
.collect(Collectors.toList());
List<Double> list2 = segments2.stream()
.map(mapper)
.collect(Collectors.toList());
return list1.equals(list2);
}
static void initSegment(MemorySegment segment) {
for (int i = 0 ; i < segment.byteSize() ; i++) {
segment.set(ValueLayout.JAVA_BYTE, 0, (byte)i);
}
}
static Object[][] spliteratorTestData = {
{ "bytes", MemoryLayout.sequenceLayout(1024, ValueLayout.JAVA_BYTE), (SpliteratorTestHelper.ContentAsserter<MemorySegment>)SegmentTestDataProvider::compareSegmentsByte },
{ "chars", MemoryLayout.sequenceLayout(1024, ValueLayout.JAVA_CHAR), (SpliteratorTestHelper.ContentAsserter<MemorySegment>)SegmentTestDataProvider::compareSegmentsChar },
{ "shorts", MemoryLayout.sequenceLayout(1024, ValueLayout.JAVA_SHORT), (SpliteratorTestHelper.ContentAsserter<MemorySegment>)SegmentTestDataProvider::compareSegmentsShort },
{ "ints", MemoryLayout.sequenceLayout(1024, ValueLayout.JAVA_INT), (SpliteratorTestHelper.ContentAsserter<MemorySegment>)SegmentTestDataProvider::compareSegmentsInt },
{ "longs", MemoryLayout.sequenceLayout(1024, ValueLayout.JAVA_LONG), (SpliteratorTestHelper.ContentAsserter<MemorySegment>)SegmentTestDataProvider::compareSegmentsLong },
{ "floats", MemoryLayout.sequenceLayout(1024, ValueLayout.JAVA_FLOAT), (SpliteratorTestHelper.ContentAsserter<MemorySegment>)SegmentTestDataProvider::compareSegmentsFloat },
{ "doubles", MemoryLayout.sequenceLayout(1024, ValueLayout.JAVA_DOUBLE), (SpliteratorTestHelper.ContentAsserter<MemorySegment>)SegmentTestDataProvider::compareSegmentsDouble },
};
// returns an array of (String name, Supplier<Spliterator<MemorySegment>>, ContentAsserter<MemorySegment>)
@DataProvider(name = "SegmentSpliterator")
public static Object[][] spliteratorProvider() {
return spliteratorTestData;
}
}

View file

@ -0,0 +1,135 @@
/*
* 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
* 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.
*/
package org.openjdk.tests.java.util.stream;
import java.util.stream.LambdaTestHelpers;
import java.util.stream.OpTestCase;
import java.util.stream.StreamTestDataProvider;
import org.testng.annotations.Test;
import java.util.Iterator;
import java.util.Comparator;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.function.UnaryOperator;
import java.util.Spliterator;
import java.util.stream.Stream;
import java.util.stream.TestData;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
/**
* SequentialOpTest
*
* @author Brian Goetz
*/
public class SequentialOpTest extends OpTestCase {
@SuppressWarnings({"rawtypes", "unchecked"})
@Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class,
groups = { "serialization-hostile" })
public void testLazy(String name, TestData.OfRef<Integer> data) {
Function<Integer, Integer> id = LambdaTestHelpers.identity();
AtomicInteger counter = new AtomicInteger();
Supplier<Stream<Integer>>[] suppliers = new Supplier[] { () -> data.stream(), () -> data.parallelStream() };
UnaryOperator<Stream<Integer>>[] configs
= new UnaryOperator[] {
(UnaryOperator<Stream<Integer>>) s -> s.peek(e -> { counter.incrementAndGet(); }),
(UnaryOperator<Stream<Integer>>) s -> s.map(id).peek(e -> { counter.incrementAndGet(); }).sequential().map(id),
(UnaryOperator<Stream<Integer>>) s -> s.map(id).peek(e -> { counter.incrementAndGet(); }).parallel().map(id),
(UnaryOperator<Stream<Integer>>) s -> s.sequential().map(id).peek(e -> {
counter.incrementAndGet();
}).map(id),
(UnaryOperator<Stream<Integer>>) s -> s.parallel().map(id).peek(e -> { counter.incrementAndGet(); }).map(id)
};
for (int i = 0; i < suppliers.length; i++) {
setContext("supplierIndex", i);
Supplier<Stream<Integer>> supp = suppliers[i];
for (int j = 0; j < configs.length; j++) {
setContext("configIndex", j);
UnaryOperator<Stream<Integer>> config = configs[j];
counter.set(0);
Stream<Integer> stream = config.apply(supp.get());
assertEquals(0, counter.get());
Iterator<Integer> iterator = stream.iterator();
assertEquals(0, counter.get());
if (iterator.hasNext())
iterator.next();
assertTrue(data.size() == 0 || counter.get() > 0);
counter.set(0);
stream = config.apply(supp.get());
Spliterator<Integer> spliterator = stream.spliterator();
assertEquals(0, counter.get());
spliterator.forEachRemaining(e -> {
});
assertTrue(data.size() == 0 || counter.get() > 0);
}
}
}
@SuppressWarnings({"rawtypes", "unchecked"})
@Test(dataProvider = "StreamTestData<Integer>.mini", dataProviderClass = StreamTestDataProvider.class)
public void testMixedSeqPar(String name, TestData.OfRef<Integer> data) {
Function<Integer, Integer> id = LambdaTestHelpers.identity();
UnaryOperator<Stream<Integer>>[] changers
= new UnaryOperator[] {
(UnaryOperator<Stream<Integer>>) s -> s,
(UnaryOperator<Stream<Integer>>) s -> s.sequential(),
(UnaryOperator<Stream<Integer>>) s -> s.parallel(),
(UnaryOperator<Stream<Integer>>) s -> s.unordered()
};
UnaryOperator<Stream<Integer>>[] stuff
= new UnaryOperator[] {
(UnaryOperator<Stream<Integer>>) s -> s,
(UnaryOperator<Stream<Integer>>) s -> s.map(id),
(UnaryOperator<Stream<Integer>>) s -> s.sorted(Comparator.naturalOrder()),
(UnaryOperator<Stream<Integer>>) s -> s.map(id).sorted(Comparator.naturalOrder()).map(id),
(UnaryOperator<Stream<Integer>>) s -> s.filter(LambdaTestHelpers.pEven).sorted(Comparator.naturalOrder()).map(id),
};
for (int c1Index = 0; c1Index < changers.length; c1Index++) {
setContext("c1Index", c1Index);
UnaryOperator<Stream<Integer>> c1 = changers[c1Index];
for (int s1Index = 0; s1Index < stuff.length; s1Index++) {
setContext("s1Index", s1Index);
UnaryOperator<Stream<Integer>> s1 = stuff[s1Index];
for (int c2Index = 0; c2Index < changers.length; c2Index++) {
setContext("c2Index", c2Index);
UnaryOperator<Stream<Integer>> c2 = changers[c2Index];
for (int s2Index = 0; s2Index < stuff.length; s2Index++) {
setContext("s2Index", s2Index);
UnaryOperator<Stream<Integer>> s2 = stuff[s2Index];
UnaryOperator<Stream<Integer>> composed = s -> s2.apply(c2.apply(s1.apply(c1.apply(s))));
exerciseOps(data, composed);
}
}
}
}
}
}

View file

@ -0,0 +1,381 @@
/*
* Copyright (c) 2012, 2021, 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 8148250 8265029
*/
package org.openjdk.tests.java.util.stream;
import org.testng.annotations.Test;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.DoubleStream;
import java.util.stream.IntStream;
import java.util.stream.LambdaTestHelpers;
import java.util.stream.LongStream;
import java.util.stream.OpTestCase;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
import java.util.stream.StreamTestDataProvider;
import java.util.stream.TestData;
import static java.util.stream.LambdaTestHelpers.*;
/**
* SliceOpTest
*
* @author Brian Goetz
*/
@Test
public class SliceOpTest extends OpTestCase {
public void testSkip() {
assertCountSum(countTo(0).stream().skip(0), 0, 0);
assertCountSum(countTo(0).stream().skip(4), 0, 0);
assertCountSum(countTo(4).stream().skip(4), 0, 0);
assertCountSum(countTo(4).stream().skip(2), 2, 7);
assertCountSum(countTo(4).stream().skip(0), 4, 10);
assertCountSum(countTo(0).parallelStream().skip(0), 0, 0);
assertCountSum(countTo(0).parallelStream().skip(4), 0, 0);
assertCountSum(countTo(4).parallelStream().skip(4), 0, 0);
assertCountSum(countTo(4).parallelStream().skip(2), 2, 7);
assertCountSum(countTo(4).parallelStream().skip(0), 4, 10);
exerciseOps(Collections.emptyList(), s -> s.skip(0), Collections.emptyList());
exerciseOps(Collections.emptyList(), s -> s.skip(10), Collections.emptyList());
exerciseOps(countTo(1), s -> s.skip(0), countTo(1));
exerciseOps(countTo(1), s -> s.skip(1), Collections.emptyList());
exerciseOps(countTo(100), s -> s.skip(0), countTo(100));
exerciseOps(countTo(100), s -> s.skip(10), range(11, 100));
exerciseOps(countTo(100), s -> s.skip(100), Collections.emptyList());
exerciseOps(countTo(100), s -> s.skip(200), Collections.emptyList());
}
public void testLimit() {
assertCountSum(countTo(0).stream().limit(4), 0, 0);
assertCountSum(countTo(2).stream().limit(4), 2, 3);
assertCountSum(countTo(4).stream().limit(4), 4, 10);
assertCountSum(countTo(8).stream().limit(4), 4, 10);
assertCountSum(countTo(0).parallelStream().limit(4), 0, 0);
assertCountSum(countTo(2).parallelStream().limit(4), 2, 3);
assertCountSum(countTo(4).parallelStream().limit(4), 4, 10);
assertCountSum(countTo(8).parallelStream().limit(4), 4, 10);
exerciseOps(Collections.emptyList(), s -> s.limit(0), Collections.emptyList());
exerciseOps(Collections.emptyList(), s -> s.limit(10), Collections.emptyList());
exerciseOps(countTo(1), s -> s.limit(0), Collections.emptyList());
exerciseOps(countTo(1), s -> s.limit(1), countTo(1));
exerciseOps(countTo(100), s -> s.limit(0), Collections.emptyList());
exerciseOps(countTo(100), s -> s.limit(10), countTo(10));
exerciseOps(countTo(100), s -> s.limit(10).limit(10), countTo(10));
exerciseOps(countTo(100), s -> s.limit(100), countTo(100));
exerciseOps(countTo(100), s -> s.limit(100).limit(10), countTo(10));
exerciseOps(countTo(100), s -> s.limit(200), countTo(100));
}
public void testSkipLimit() {
exerciseOps(Collections.emptyList(), s -> s.skip(0).limit(0), Collections.emptyList());
exerciseOps(Collections.emptyList(), s -> s.skip(0).limit(10), Collections.emptyList());
exerciseOps(Collections.emptyList(), s -> s.skip(10).limit(0), Collections.emptyList());
exerciseOps(Collections.emptyList(), s -> s.skip(10).limit(10), Collections.emptyList());
exerciseOps(countTo(100), s -> s.skip(0).limit(100), countTo(100));
exerciseOps(countTo(100), s -> s.skip(0).limit(10), countTo(10));
exerciseOps(countTo(100), s -> s.skip(0).limit(0), Collections.emptyList());
exerciseOps(countTo(100), s -> s.skip(10).limit(100), range(11, 100));
exerciseOps(countTo(100), s -> s.skip(10).limit(10), range(11, 20));
exerciseOps(countTo(100), s -> s.skip(10).limit(0), Collections.emptyList());
exerciseOps(countTo(100), s -> s.skip(100).limit(100), Collections.emptyList());
exerciseOps(countTo(100), s -> s.skip(100).limit(10), Collections.emptyList());
exerciseOps(countTo(100), s -> s.skip(100).limit(0), Collections.emptyList());
exerciseOps(countTo(100), s -> s.skip(200).limit(100), Collections.emptyList());
exerciseOps(countTo(100), s -> s.skip(200).limit(10), Collections.emptyList());
exerciseOps(countTo(100), s -> s.skip(200).limit(0), Collections.emptyList());
}
public void testSlice() {
exerciseOps(Collections.emptyList(), s -> s.skip(0).limit(0), Collections.emptyList());
exerciseOps(Collections.emptyList(), s -> s.skip(0).limit(10), Collections.emptyList());
exerciseOps(Collections.emptyList(), s -> s.skip(10).limit(10), Collections.emptyList());
exerciseOps(Collections.emptyList(), s -> s.skip(10).limit(20), Collections.emptyList());
exerciseOps(countTo(100), s -> s.skip(0).limit(100), countTo(100));
exerciseOps(countTo(100), s -> s.skip(0).limit(10), countTo(10));
exerciseOps(countTo(100), s -> s.skip(0).limit(0), Collections.emptyList());
exerciseOps(countTo(100), s -> s.skip(10).limit(100), range(11, 100));
exerciseOps(countTo(100), s -> s.skip(10).limit(10), range(11, 20));
exerciseOps(countTo(100), s -> s.skip(10).limit(0), Collections.emptyList());
exerciseOps(countTo(100), s -> s.skip(100).limit(100), Collections.emptyList());
exerciseOps(countTo(100), s -> s.skip(100).limit(10), Collections.emptyList());
exerciseOps(countTo(100), s -> s.skip(100).limit(0), Collections.emptyList());
exerciseOps(countTo(100), s -> s.skip(200).limit(100), Collections.emptyList());
exerciseOps(countTo(100), s -> s.skip(200).limit(10), Collections.emptyList());
exerciseOps(countTo(100), s -> s.skip(200).limit(0), Collections.emptyList());
}
private int sliceSize(int dataSize, int skip, int limit) {
int size = Math.max(0, dataSize - skip);
if (limit >= 0)
size = Math.min(size, limit);
return size;
}
private int sliceSize(int dataSize, int skip) {
return Math.max(0, dataSize - skip);
}
@Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class,
groups = { "serialization-hostile" })
public void testSkipOps(String name, TestData.OfRef<Integer> data) {
List<Integer> skips = sizes(data.size());
for (int s : skips) {
setContext("skip", s);
testSliceMulti(data,
sliceSize(data.size(), s),
st -> st.skip(s),
st -> st.skip(s),
st -> st.skip(s),
st -> st.skip(s));
testSliceMulti(data,
sliceSize(sliceSize(data.size(), s), s/2),
st -> st.skip(s).skip(s / 2),
st -> st.skip(s).skip(s / 2),
st -> st.skip(s).skip(s / 2),
st -> st.skip(s).skip(s / 2));
}
}
@Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class,
groups = { "serialization-hostile" })
public void testSkipLimitOps(String name, TestData.OfRef<Integer> data) {
List<Integer> skips = sizes(data.size());
List<Integer> limits = skips;
for (int s : skips) {
setContext("skip", s);
for (int l : limits) {
setContext("limit", l);
testSliceMulti(data,
sliceSize(sliceSize(data.size(), s), 0, l),
st -> st.skip(s).limit(l),
st -> st.skip(s).limit(l),
st -> st.skip(s).limit(l),
st -> st.skip(s).limit(l));
}
}
}
@Test(groups = { "serialization-hostile" })
public void testSkipLimitOpsWithNonSplittingSpliterator() {
class NonSplittingNotSubsizedOrderedSpliterator<T> implements Spliterator<T> {
Spliterator<T> s;
NonSplittingNotSubsizedOrderedSpliterator(Spliterator<T> s) {
assert s.hasCharacteristics(Spliterator.ORDERED);
this.s = s;
}
@Override
public boolean tryAdvance(Consumer<? super T> action) {
return s.tryAdvance(action);
}
@Override
public void forEachRemaining(Consumer<? super T> action) {
s.forEachRemaining(action);
}
@Override
public Spliterator<T> trySplit() {
return null;
}
@Override
public long estimateSize() {
return s.estimateSize();
}
@Override
public int characteristics() {
return s.characteristics() & ~(Spliterator.SUBSIZED);
}
@Override
public Comparator<? super T> getComparator() {
return s.getComparator();
}
}
List<Integer> list = IntStream.range(0, 100).boxed().collect(Collectors.toList());
TestData.OfRef<Integer> data = TestData.Factory.ofSupplier(
"Non splitting, not SUBSIZED, ORDERED, stream",
() -> StreamSupport.stream(new NonSplittingNotSubsizedOrderedSpliterator<>(list.spliterator()), false));
testSkipLimitOps("testSkipLimitOpsWithNonSplittingSpliterator", data);
}
@Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class,
groups = { "serialization-hostile" })
public void testLimitOps(String name, TestData.OfRef<Integer> data) {
List<Integer> limits = sizes(data.size());
for (int l : limits) {
setContext("limit", l);
testSliceMulti(data,
sliceSize(data.size(), 0, l),
st -> st.limit(l),
st -> st.limit(l),
st -> st.limit(l),
st -> st.limit(l));
}
for (int l : limits) {
setContext("limit", l);
testSliceMulti(data,
sliceSize(sliceSize(data.size(), 0, l), 0, l / 2),
st -> st.limit(l).limit(l / 2),
st -> st.limit(l).limit(l / 2),
st -> st.limit(l).limit(l / 2),
st -> st.limit(l).limit(l / 2));
}
}
private ResultAsserter<Iterable<Integer>> sliceResultAsserter(Iterable<Integer> data,
int expectedSize) {
return (act, exp, ord, par) -> {
if (par & !ord) {
List<Integer> expected = new ArrayList<>();
data.forEach(expected::add);
List<Integer> actual = new ArrayList<>();
act.forEach(actual::add);
assertEquals(actual.size(), expectedSize);
assertTrue(expected.containsAll(actual));
}
else {
LambdaTestHelpers.assertContents(act, exp);
}
};
}
private void testSliceMulti(TestData.OfRef<Integer> data,
int expectedSize,
Function<Stream<Integer>, Stream<Integer>> mRef,
Function<IntStream, IntStream> mInt,
Function<LongStream, LongStream> mLong,
Function<DoubleStream, DoubleStream> mDouble) {
@SuppressWarnings({ "rawtypes", "unchecked" })
Function<Stream<Integer>, Stream<Integer>>[] ms = new Function[4];
ms[0] = mRef;
ms[1] = s -> mInt.apply(s.mapToInt(e -> e)).mapToObj(e -> e);
ms[2] = s -> mLong.apply(s.mapToLong(e -> e)).mapToObj(e -> (int) e);
ms[3] = s -> mDouble.apply(s.mapToDouble(e -> e)).mapToObj(e -> (int) e);
testSliceMulti(data, expectedSize, ms);
}
@SafeVarargs
private final void testSliceMulti(TestData.OfRef<Integer> data,
int expectedSize,
Function<Stream<Integer>, Stream<Integer>>... ms) {
for (int i = 0; i < ms.length; i++) {
setContext("mIndex", i);
Function<Stream<Integer>, Stream<Integer>> m = ms[i];
Collection<Integer> sr = withData(data)
.stream(m)
.resultAsserter(sliceResultAsserter(data, expectedSize))
.exercise();
assertEquals(sr.size(), expectedSize);
}
}
public void testLimitSort() {
List<Integer> l = countTo(100);
Collections.reverse(l);
exerciseOps(l, s -> s.limit(10).sorted(Comparator.naturalOrder()));
}
@Test(groups = { "serialization-hostile" })
public void testLimitShortCircuit() {
for (int l : Arrays.asList(0, 10)) {
setContext("l", l);
AtomicInteger ai = new AtomicInteger();
countTo(100).stream()
.peek(i -> ai.getAndIncrement())
.limit(l).toArray();
// For the case of a zero limit, one element will get pushed through the sink chain
assertEquals(ai.get(), l, "tee block was called too many times");
}
}
private List<Integer> sizes(int size) {
if (size < 4) {
return Arrays.asList(0, 1, 2, 3, 4, 6);
}
else {
return Arrays.asList(0, 1, size / 2, size - 1, size, size + 1, 2 * size);
}
}
public void testLimitParallelHugeInput() {
for (int n : new int[] {10, 100, 1000, 10000}) {
long[] actual = LongStream.range(0, Long.MAX_VALUE)
.parallel().filter(x -> true) // remove SIZED
.limit(n).toArray();
assertEquals(LongStream.range(0, n).toArray(), actual);
}
}
public void testSliceOpsSpliteratorPreservesSized() {
var parSpliterator = IntStream.range(0, 1000).parallel().skip(50).limit(800).spliterator();
assertTrue(parSpliterator.hasCharacteristics(Spliterator.SIZED));
assertTrue(parSpliterator.hasCharacteristics(Spliterator.SUBSIZED));
assertEquals(parSpliterator.getExactSizeIfKnown(), 800);
// Original spliterator is split to [0..499] and [500..999] parts
// due to skip+limit, we have [50..499] and [500..849]
var prefix = parSpliterator.trySplit();
assertNotNull(prefix);
assertTrue(parSpliterator.hasCharacteristics(Spliterator.SIZED));
assertTrue(parSpliterator.hasCharacteristics(Spliterator.SUBSIZED));
assertEquals(parSpliterator.getExactSizeIfKnown(), 350);
assertTrue(prefix.hasCharacteristics(Spliterator.SIZED));
assertTrue(prefix.hasCharacteristics(Spliterator.SUBSIZED));
assertEquals(prefix.getExactSizeIfKnown(), 450);
var seqSpliterator = IntStream.range(0, 1000).skip(50).limit(800).spliterator();
assertTrue(seqSpliterator.hasCharacteristics(Spliterator.SIZED));
assertTrue(seqSpliterator.hasCharacteristics(Spliterator.SUBSIZED));
assertEquals(seqSpliterator.getExactSizeIfKnown(), 800);
}
}

View file

@ -0,0 +1,366 @@
/*
* Copyright (c) 2012, 2025, 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.
*/
package org.openjdk.tests.java.util.stream;
import org.testng.annotations.Test;
import java.util.*;
import java.util.Comparator;
import java.util.Spliterators;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.*;
import static java.util.stream.LambdaTestHelpers.*;
/**
* SortedOpTest
*
* @author Brian Goetz
*/
@Test
public class SortedOpTest extends OpTestCase {
public void testRefStreamTooLarge() {
Function<LongStream, Stream<Long>> f = s ->
// Clear the SORTED flag
s.mapToObj(i -> i)
.sorted();
testStreamTooLarge(f, Stream::findFirst);
}
public void testIntStreamTooLarge() {
Function<LongStream, IntStream> f = s ->
// Clear the SORTED flag
s.mapToInt(i -> (int) i)
.sorted();
testStreamTooLarge(f, IntStream::findFirst);
}
public void testLongStreamTooLarge() {
Function<LongStream, LongStream> f = s ->
// Clear the SORTED flag
s.map(i -> i)
.sorted();
testStreamTooLarge(f, LongStream::findFirst);
}
public void testDoubleStreamTooLarge() {
Function<LongStream, DoubleStream> f = s ->
// Clear the SORTED flag
s.mapToDouble(i -> (double) i)
.sorted();
testStreamTooLarge(f, DoubleStream::findFirst);
}
<T, S extends BaseStream<T, S>> void testStreamTooLarge(Function<LongStream, S> s,
Function<S, ?> terminal) {
// Set up conditions for a large input > maximum array size
Supplier<LongStream> input = () -> LongStream.range(0, 1L + Integer.MAX_VALUE);
// Transformation functions
List<Function<LongStream, LongStream>> transforms = Arrays.asList(
ls -> ls,
ls -> ls.parallel(),
// Clear the SIZED flag
ls -> ls.limit(Long.MAX_VALUE),
ls -> ls.limit(Long.MAX_VALUE).parallel());
for (Function<LongStream, LongStream> transform : transforms) {
RuntimeException caught = null;
try {
terminal.apply(s.apply(transform.apply(input.get())));
} catch (RuntimeException e) {
caught = e;
}
assertNotNull(caught, "Expected an instance of exception IllegalArgumentException but no exception thrown");
assertTrue(caught instanceof IllegalArgumentException,
String.format("Expected an instance of exception IllegalArgumentException but got %s", caught));
}
}
public void testSorted() {
assertCountSum(countTo(0).stream().sorted(), 0, 0);
assertCountSum(countTo(10).stream().sorted(), 10, 55);
assertCountSum(countTo(10).stream().sorted(cInteger.reversed()), 10, 55);
List<Integer> to10 = countTo(10);
assertSorted(to10.stream().sorted(cInteger.reversed()).iterator(), cInteger.reversed());
Collections.reverse(to10);
assertSorted(to10.stream().sorted().iterator());
assertSorted(to10.stream().sorted(Comparator.naturalOrder()).iterator());
Spliterator<Integer> s = to10.stream().sorted().spliterator();
assertTrue(s.hasCharacteristics(Spliterator.SORTED));
s = to10.stream().sorted(Comparator.naturalOrder()).spliterator();
assertTrue(s.hasCharacteristics(Spliterator.SORTED));
s = to10.stream().sorted(cInteger.reversed()).spliterator();
assertFalse(s.hasCharacteristics(Spliterator.SORTED));
}
@Test(groups = { "serialization-hostile" })
public void testSequentialShortCircuitTerminal() {
// The sorted op for sequential evaluation will buffer all elements when
// accepting then at the end sort those elements and push those elements
// downstream
// A peek operation is added in-between the sorted() and terminal
// operation that counts the number of calls to its consumer and
// asserts that the number of calls is at most the required quantity
List<Integer> l = Arrays.asList(5, 4, 3, 2, 1);
Function<Integer, Stream<Integer>> knownSize = i -> assertNCallsOnly(
l.stream().sorted(), Stream::peek, i);
Function<Integer, Stream<Integer>> unknownSize = i -> assertNCallsOnly
(unknownSizeStream(l).sorted(), Stream::peek, i);
// Find
assertEquals(knownSize.apply(1).findFirst(), Optional.of(1));
assertEquals(knownSize.apply(1).findAny(), Optional.of(1));
assertEquals(unknownSize.apply(1).findFirst(), Optional.of(1));
assertEquals(unknownSize.apply(1).findAny(), Optional.of(1));
// Match
assertEquals(knownSize.apply(2).anyMatch(i -> i == 2), true);
assertEquals(knownSize.apply(2).noneMatch(i -> i == 2), false);
assertEquals(knownSize.apply(2).allMatch(i -> i == 2), false);
assertEquals(unknownSize.apply(2).anyMatch(i -> i == 2), true);
assertEquals(unknownSize.apply(2).noneMatch(i -> i == 2), false);
assertEquals(unknownSize.apply(2).allMatch(i -> i == 2), false);
}
private <T> Stream<T> unknownSizeStream(List<T> l) {
return StreamSupport.stream(Spliterators.spliteratorUnknownSize(l.iterator(), 0), false);
}
@Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
public void testOps(String name, TestData.OfRef<Integer> data) {
Collection<Integer> result = exerciseOpsInt(data, Stream::sorted, IntStream::sorted, LongStream::sorted, DoubleStream::sorted);
assertSorted(result.iterator());
assertContentsUnordered(data, result);
result = exerciseOps(data, s -> s.sorted(cInteger.reversed()));
assertSorted(result.iterator(), cInteger.reversed());
assertContentsUnordered(data, result);
}
@Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
public void testSortSort(String name, TestData.OfRef<Integer> data) {
// For parallel cases ensure the size is known
Collection<Integer> result = withData(data)
.stream(s -> s.sorted().sorted(),
new CollectorOps.TestParallelSizedOp<Integer>())
.exercise();
assertSorted(result);
assertContentsUnordered(data, result);
result = withData(data)
.stream(s -> s.sorted(cInteger.reversed()).sorted(cInteger.reversed()),
new CollectorOps.TestParallelSizedOp<Integer>())
.exercise();
assertSorted(result, cInteger.reversed());
assertContentsUnordered(data, result);
result = withData(data)
.stream(s -> s.sorted().sorted(cInteger.reversed()),
new CollectorOps.TestParallelSizedOp<Integer>())
.exercise();
assertSorted(result, cInteger.reversed());
assertContentsUnordered(data, result);
result = withData(data)
.stream(s -> s.sorted(cInteger.reversed()).sorted(),
new CollectorOps.TestParallelSizedOp<Integer>())
.exercise();
assertSorted(result);
assertContentsUnordered(data, result);
}
//
@Test(groups = { "serialization-hostile" })
public void testIntSequentialShortCircuitTerminal() {
int[] a = new int[]{5, 4, 3, 2, 1};
Function<Integer, IntStream> knownSize = i -> assertNCallsOnly(
Arrays.stream(a).sorted(), (s, c) -> s.peek(c::accept), i);
Function<Integer, IntStream> unknownSize = i -> assertNCallsOnly
(unknownSizeIntStream(a).sorted(), (s, c) -> s.peek(c::accept), i);
// Find
assertEquals(knownSize.apply(1).findFirst(), OptionalInt.of(1));
assertEquals(knownSize.apply(1).findAny(), OptionalInt.of(1));
assertEquals(unknownSize.apply(1).findFirst(), OptionalInt.of(1));
assertEquals(unknownSize.apply(1).findAny(), OptionalInt.of(1));
// Match
assertEquals(knownSize.apply(2).anyMatch(i -> i == 2), true);
assertEquals(knownSize.apply(2).noneMatch(i -> i == 2), false);
assertEquals(knownSize.apply(2).allMatch(i -> i == 2), false);
assertEquals(unknownSize.apply(2).anyMatch(i -> i == 2), true);
assertEquals(unknownSize.apply(2).noneMatch(i -> i == 2), false);
assertEquals(unknownSize.apply(2).allMatch(i -> i == 2), false);
}
private IntStream unknownSizeIntStream(int[] a) {
return StreamSupport.intStream(Spliterators.spliteratorUnknownSize(Spliterators.iterator(Arrays.spliterator(a)), 0), false);
}
@Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
public void testIntOps(String name, TestData.OfInt data) {
Collection<Integer> result = exerciseOps(data, s -> s.sorted());
assertSorted(result);
assertContentsUnordered(data, result);
}
@Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
public void testIntSortSort(String name, TestData.OfInt data) {
// For parallel cases ensure the size is known
Collection<Integer> result = withData(data)
.stream(s -> s.sorted().sorted(), new CollectorOps.TestParallelSizedOp.OfInt())
.exercise();
assertSorted(result);
assertContentsUnordered(data, result);
}
//
@Test(groups = { "serialization-hostile" })
public void testLongSequentialShortCircuitTerminal() {
long[] a = new long[]{5, 4, 3, 2, 1};
Function<Integer, LongStream> knownSize = i -> assertNCallsOnly(
Arrays.stream(a).sorted(), (s, c) -> s.peek(c::accept), i);
Function<Integer, LongStream> unknownSize = i -> assertNCallsOnly
(unknownSizeLongStream(a).sorted(), (s, c) -> s.peek(c::accept), i);
// Find
assertEquals(knownSize.apply(1).findFirst(), OptionalLong.of(1));
assertEquals(knownSize.apply(1).findAny(), OptionalLong.of(1));
assertEquals(unknownSize.apply(1).findFirst(), OptionalLong.of(1));
assertEquals(unknownSize.apply(1).findAny(), OptionalLong.of(1));
// Match
assertEquals(knownSize.apply(2).anyMatch(i -> i == 2), true);
assertEquals(knownSize.apply(2).noneMatch(i -> i == 2), false);
assertEquals(knownSize.apply(2).allMatch(i -> i == 2), false);
assertEquals(unknownSize.apply(2).anyMatch(i -> i == 2), true);
assertEquals(unknownSize.apply(2).noneMatch(i -> i == 2), false);
assertEquals(unknownSize.apply(2).allMatch(i -> i == 2), false);
}
private LongStream unknownSizeLongStream(long[] a) {
return StreamSupport.longStream(Spliterators.spliteratorUnknownSize(Spliterators.iterator(Arrays.spliterator(a)), 0), false);
}
@Test(dataProvider = "LongStreamTestData", dataProviderClass = LongStreamTestDataProvider.class)
public void testLongOps(String name, TestData.OfLong data) {
Collection<Long> result = exerciseOps(data, s -> s.sorted());
assertSorted(result);
assertContentsUnordered(data, result);
}
@Test(dataProvider = "LongStreamTestData", dataProviderClass = LongStreamTestDataProvider.class)
public void testLongSortSort(String name, TestData.OfLong data) {
// For parallel cases ensure the size is known
Collection<Long> result = withData(data)
.stream(s -> s.sorted().sorted(), new CollectorOps.TestParallelSizedOp.OfLong())
.exercise();
assertSorted(result);
assertContentsUnordered(data, result);
}
//
@Test(groups = { "serialization-hostile" })
public void testDoubleSequentialShortCircuitTerminal() {
double[] a = new double[]{5.0, 4.0, 3.0, 2.0, 1.0};
Function<Integer, DoubleStream> knownSize = i -> assertNCallsOnly(
Arrays.stream(a).sorted(), (s, c) -> s.peek(c::accept), i);
Function<Integer, DoubleStream> unknownSize = i -> assertNCallsOnly
(unknownSizeDoubleStream(a).sorted(), (s, c) -> s.peek(c::accept), i);
// Find
assertEquals(knownSize.apply(1).findFirst(), OptionalDouble.of(1));
assertEquals(knownSize.apply(1).findAny(), OptionalDouble.of(1));
assertEquals(unknownSize.apply(1).findFirst(), OptionalDouble.of(1));
assertEquals(unknownSize.apply(1).findAny(), OptionalDouble.of(1));
// Match
assertEquals(knownSize.apply(2).anyMatch(i -> i == 2.0), true);
assertEquals(knownSize.apply(2).noneMatch(i -> i == 2.0), false);
assertEquals(knownSize.apply(2).allMatch(i -> i == 2.0), false);
assertEquals(unknownSize.apply(2).anyMatch(i -> i == 2.0), true);
assertEquals(unknownSize.apply(2).noneMatch(i -> i == 2.0), false);
assertEquals(unknownSize.apply(2).allMatch(i -> i == 2.0), false);
}
private DoubleStream unknownSizeDoubleStream(double[] a) {
return StreamSupport.doubleStream(Spliterators.spliteratorUnknownSize(Spliterators.iterator(Arrays.spliterator(a)), 0), false);
}
@Test(dataProvider = "DoubleStreamTestData", dataProviderClass = DoubleStreamTestDataProvider.class)
public void testDoubleOps(String name, TestData.OfDouble data) {
Collection<Double> result = exerciseOps(data, s -> s.sorted());
assertSorted(result);
assertContentsUnordered(data, result);
}
@Test(dataProvider = "DoubleStreamTestData", dataProviderClass = DoubleStreamTestDataProvider.class)
public void testDoubleSortSort(String name, TestData.OfDouble data) {
// For parallel cases ensure the size is known
Collection<Double> result = withData(data)
.stream(s -> s.sorted().sorted(), new CollectorOps.TestParallelSizedOp.OfDouble())
.exercise();
assertSorted(result);
assertContentsUnordered(data, result);
}
/**
* Interpose a consumer that asserts it is called at most N times.
*/
<T, S extends BaseStream<T, S>, R> S assertNCallsOnly(S s, BiFunction<S, Consumer<T>, S> pf, int n) {
AtomicInteger boxedInt = new AtomicInteger();
return pf.apply(s, i -> {
assertFalse(boxedInt.incrementAndGet() > n, "Intermediate op called more than " + n + " time(s)");
});
}
}

View file

@ -0,0 +1,75 @@
/*
* Copyright (c) 2012, 2022, 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.
*/
package org.openjdk.tests.java.util.stream;
import java.lang.foreign.Arena;
import java.lang.foreign.MemorySegment;
import java.lang.foreign.SequenceLayout;
import org.testng.annotations.Test;
import java.util.function.Supplier;
import java.util.Spliterator;
import java.util.SpliteratorTestHelper;
import java.util.stream.*;
import static org.testng.Assert.*;
import static org.testng.Assert.assertEquals;
/**
* SpliteratorTest
*
* @author Brian Goetz
*/
@Test
public class SpliteratorTest {
@Test(dataProvider = "Spliterator<Integer>", dataProviderClass = StreamTestDataProvider.class )
public void testSpliterator(String name, Supplier<Spliterator<Integer>> supplier) {
SpliteratorTestHelper.testSpliterator(supplier);
}
@Test(dataProvider = "IntSpliterator", dataProviderClass = IntStreamTestDataProvider.class )
public void testIntSpliterator(String name, Supplier<Spliterator.OfInt> supplier) {
SpliteratorTestHelper.testIntSpliterator(supplier);
}
@Test(dataProvider = "LongSpliterator", dataProviderClass = LongStreamTestDataProvider.class )
public void testLongSpliterator(String name, Supplier<Spliterator.OfLong> supplier) {
SpliteratorTestHelper.testLongSpliterator(supplier);
}
@Test(dataProvider = "DoubleSpliterator", dataProviderClass = DoubleStreamTestDataProvider.class )
public void testDoubleSpliterator(String name, Supplier<Spliterator.OfDouble> supplier) {
SpliteratorTestHelper.testDoubleSpliterator(supplier);
}
@Test(dataProvider = "SegmentSpliterator", dataProviderClass = SegmentTestDataProvider.class )
public void testSegmentSpliterator(String name, SequenceLayout layout, SpliteratorTestHelper.ContentAsserter<MemorySegment> contentAsserter) {
try (Arena arena = Arena.ofConfined()) {
MemorySegment segment = arena.allocate(layout);
SegmentTestDataProvider.initSegment(segment);
SpliteratorTestHelper.testSpliterator(() -> segment.spliterator(layout),
SegmentTestDataProvider::segmentCopier, contentAsserter);
}
}
}

View file

@ -0,0 +1,324 @@
/*
* 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
* 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.
*/
package org.openjdk.tests.java.util.stream;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.function.Function;
import java.util.stream.DoubleStream;
import java.util.stream.IntStream;
import java.util.stream.LambdaTestHelpers;
import java.util.stream.LongStream;
import java.util.stream.OpTestCase;
import java.util.stream.Stream;
import java.util.stream.TestData;
import static java.util.stream.Collectors.toList;
import static java.util.stream.ThrowableHelper.checkISE;
@Test
public class StreamBuilderTest extends OpTestCase {
List<Integer> sizes = Arrays.asList(0, 1, 4, 16, 256,
1023, 1024, 1025,
2047, 2048, 2049,
1024 * 32 - 1, 1024 * 32, 1024 * 32 + 1);
@DataProvider(name = "sizes")
public Object[][] createStreamBuilders() {
return sizes.stream().map(i -> new Object[] { i }).toArray(Object[][]::new);
}
@Test
public void testOfNullableWithNonNull() {
TestData.OfRef<Integer> data = TestData.Factory.ofSupplier("{1}",
() -> Stream.ofNullable(1));
withData(data).
stream(s -> s).
expectedResult(Collections.singletonList(1)).
exercise();
}
@Test
public void testOfNullableWithNull() {
TestData.OfRef<Integer> data = TestData.Factory.ofSupplier("{null})",
() -> Stream.ofNullable(null));
withData(data).
stream(s -> s).
expectedResult(Collections.emptyList()).
exercise();
}
@Test
public void testSingleton() {
TestData.OfRef<Integer> data = TestData.Factory.ofSupplier("{1}",
() -> Stream.of(1));
withData(data).
stream(s -> s).
expectedResult(Collections.singletonList(1)).
exercise();
withData(data).
stream(s -> s.map(LambdaTestHelpers.identity())).
expectedResult(Collections.singletonList(1)).
exercise();
}
@Test(dataProvider = "sizes")
public void testAfterBuilding(int size) {
Stream.Builder<Integer> sb = Stream.builder();
IntStream.range(0, size).boxed().forEach(sb);
sb.build();
checkISE(() -> sb.accept(1));
checkISE(() -> sb.add(1));
checkISE(() -> sb.build());
}
@Test(dataProvider = "sizes", groups = { "serialization-hostile" })
public void testStreamBuilder(int size) {
testStreamBuilder(size, (s) -> {
Stream.Builder<Integer> sb = Stream.builder();
IntStream.range(0, s).boxed().forEach(sb);
return sb.build();
});
testStreamBuilder(size, (s) -> {
Stream.Builder<Integer> sb = Stream.builder();
IntStream.range(0, s).boxed().forEach(i -> {
Stream.Builder<Integer> _sb = sb.add(i);
assertTrue(sb == _sb);
});
return sb.build();
});
}
private void testStreamBuilder(int size, Function<Integer, Stream<Integer>> supplier) {
TestData.OfRef<Integer> data = TestData.Factory.ofSupplier(String.format("[0, %d)", size),
() -> supplier.apply(size));
withData(data).
stream(s -> s).
expectedResult(IntStream.range(0, size).boxed().collect(toList())).
exercise();
withData(data).
stream(s -> s.map(LambdaTestHelpers.identity())).
expectedResult(IntStream.range(0, size).boxed().collect(toList())).
exercise();
}
//
@Test
public void testIntSingleton() {
TestData.OfInt data = TestData.Factory.ofIntSupplier("{1}",
() -> IntStream.of(1));
withData(data).
stream(s -> s).
expectedResult(Collections.singletonList(1)).
exercise();
withData(data).
stream(s -> s.map(i -> i)).
expectedResult(Collections.singletonList(1)).
exercise();
}
@Test(dataProvider = "sizes")
public void testIntAfterBuilding(int size) {
IntStream.Builder sb = IntStream.builder();
IntStream.range(0, size).forEach(sb);
sb.build();
checkISE(() -> sb.accept(1));
checkISE(() -> sb.add(1));
checkISE(() -> sb.build());
}
@Test(dataProvider = "sizes", groups = { "serialization-hostile" })
public void testIntStreamBuilder(int size) {
testIntStreamBuilder(size, (s) -> {
IntStream.Builder sb = IntStream.builder();
IntStream.range(0, s).forEach(sb);
return sb.build();
});
testIntStreamBuilder(size, (s) -> {
IntStream.Builder sb = IntStream.builder();
IntStream.range(0, s).forEach(i -> {
IntStream.Builder _sb = sb.add(i);
assertTrue(sb == _sb);
});
return sb.build();
});
}
private void testIntStreamBuilder(int size, Function<Integer, IntStream> supplier) {
TestData.OfInt data = TestData.Factory.ofIntSupplier(String.format("[0, %d)", size),
() -> supplier.apply(size));
withData(data).
stream(s -> s).
expectedResult(IntStream.range(0, size).toArray()).
exercise();
withData(data).
stream(s -> s.map(i -> i)).
expectedResult(IntStream.range(0, size).toArray()).
exercise();
}
//
@Test
public void testLongSingleton() {
TestData.OfLong data = TestData.Factory.ofLongSupplier("{1}",
() -> LongStream.of(1));
withData(data).
stream(s -> s).
expectedResult(Collections.singletonList(1L)).
exercise();
withData(data).
stream(s -> s.map(i -> i)).
expectedResult(Collections.singletonList(1L)).
exercise();
}
@Test(dataProvider = "sizes")
public void testLongAfterBuilding(int size) {
LongStream.Builder sb = LongStream.builder();
LongStream.range(0, size).forEach(sb);
sb.build();
checkISE(() -> sb.accept(1));
checkISE(() -> sb.add(1));
checkISE(() -> sb.build());
}
@Test(dataProvider = "sizes", groups = { "serialization-hostile" })
public void testLongStreamBuilder(int size) {
testLongStreamBuilder(size, (s) -> {
LongStream.Builder sb = LongStream.builder();
LongStream.range(0, s).forEach(sb);
return sb.build();
});
testLongStreamBuilder(size, (s) -> {
LongStream.Builder sb = LongStream.builder();
LongStream.range(0, s).forEach(i -> {
LongStream.Builder _sb = sb.add(i);
assertTrue(sb == _sb);
});
return sb.build();
});
}
private void testLongStreamBuilder(int size, Function<Integer, LongStream> supplier) {
TestData.OfLong data = TestData.Factory.ofLongSupplier(String.format("[0, %d)", size),
() -> supplier.apply(size));
withData(data).
stream(s -> s).
expectedResult(LongStream.range(0, size).toArray()).
exercise();
withData(data).
stream(s -> s.map(i -> i)).
expectedResult(LongStream.range(0, size).toArray()).
exercise();
}
//
@Test
public void testDoubleSingleton() {
TestData.OfDouble data = TestData.Factory.ofDoubleSupplier("{1}", () -> DoubleStream.of(1));
withData(data).
stream(s -> s).
expectedResult(Collections.singletonList(1.0)).
exercise();
withData(data).
stream(s -> s.map(i -> i)).
expectedResult(Collections.singletonList(1.0)).
exercise();
}
@Test(dataProvider = "sizes")
public void testDoubleAfterBuilding(int size) {
DoubleStream.Builder sb = DoubleStream.builder();
IntStream.range(0, size).asDoubleStream().forEach(sb);
sb.build();
checkISE(() -> sb.accept(1));
checkISE(() -> sb.add(1));
checkISE(() -> sb.build());
}
@Test(dataProvider = "sizes", groups = { "serialization-hostile" })
public void testDoubleStreamBuilder(int size) {
testDoubleStreamBuilder(size, (s) -> {
DoubleStream.Builder sb = DoubleStream.builder();
IntStream.range(0, s).asDoubleStream().forEach(sb);
return sb.build();
});
testDoubleStreamBuilder(size, (s) -> {
DoubleStream.Builder sb = DoubleStream.builder();
IntStream.range(0, s).asDoubleStream().forEach(i -> {
DoubleStream.Builder _sb = sb.add(i);
assertTrue(sb == _sb);
});
return sb.build();
});
}
private void testDoubleStreamBuilder(int size, Function<Integer, DoubleStream> supplier) {
TestData.OfDouble data = TestData.Factory.ofDoubleSupplier(String.format("[0, %d)", size),
() -> supplier.apply(size));
withData(data).
stream(s -> s).
expectedResult(IntStream.range(0, size).asDoubleStream().toArray()).
exercise();
withData(data).
stream(s -> s.map(i -> i)).
expectedResult(IntStream.range(0, size).asDoubleStream().toArray()).
exercise();
}
}

View file

@ -0,0 +1,191 @@
/*
* Copyright (c) 2014, 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
* @summary close handlers and closing streams
* @bug 8044047 8147505
*/
package org.openjdk.tests.java.util.stream;
import java.util.Arrays;
import java.util.stream.OpTestCase;
import java.util.stream.Stream;
import org.testng.annotations.Test;
import static java.util.stream.LambdaTestHelpers.countTo;
import static java.util.stream.ThrowableHelper.checkNPE;
import static java.util.stream.ThrowableHelper.checkISE;
@Test(groups = { "serialization-hostile" })
public class StreamCloseTest extends OpTestCase {
public void testNullCloseHandler() {
checkNPE(() -> Stream.of(1).onClose(null));
}
public void testEmptyCloseHandler() {
try (Stream<Integer> ints = countTo(100).stream()) {
ints.forEach(i -> {});
}
}
public void testOneCloseHandler() {
final boolean[] holder = new boolean[1];
Runnable closer = () -> { holder[0] = true; };
try (Stream<Integer> ints = countTo(100).stream()) {
ints.onClose(closer);
ints.forEach(i -> {});
}
assertTrue(holder[0]);
Arrays.fill(holder, false);
try (Stream<Integer> ints = countTo(100).stream().onClose(closer)) {
ints.forEach(i -> {});
}
assertTrue(holder[0]);
Arrays.fill(holder, false);
try (Stream<Integer> ints = countTo(100).stream().filter(e -> true).onClose(closer)) {
ints.forEach(i -> {});
}
assertTrue(holder[0]);
Arrays.fill(holder, false);
try (Stream<Integer> ints = countTo(100).stream().filter(e -> true).onClose(closer).filter(e -> true)) {
ints.forEach(i -> {});
}
assertTrue(holder[0]);
}
public void testTwoCloseHandlers() {
final boolean[] holder = new boolean[2];
Runnable close1 = () -> { holder[0] = true; };
Runnable close2 = () -> { holder[1] = true; };
try (Stream<Integer> ints = countTo(100).stream()) {
ints.onClose(close1).onClose(close2);
ints.forEach(i -> {});
}
assertTrue(holder[0] && holder[1]);
Arrays.fill(holder, false);
try (Stream<Integer> ints = countTo(100).stream().onClose(close1).onClose(close2)) {
ints.forEach(i -> {});
}
assertTrue(holder[0] && holder[1]);
Arrays.fill(holder, false);
try (Stream<Integer> ints = countTo(100).stream().filter(e -> true).onClose(close1).onClose(close2)) {
ints.forEach(i -> {});
}
assertTrue(holder[0] && holder[1]);
Arrays.fill(holder, false);
try (Stream<Integer> ints = countTo(100).stream().filter(e -> true).onClose(close1).onClose(close2).filter(e -> true)) {
ints.forEach(i -> {});
}
assertTrue(holder[0] && holder[1]);
}
public void testCascadedExceptions() {
final boolean[] holder = new boolean[3];
boolean caught = false;
Runnable close1 = () -> { holder[0] = true; throw new RuntimeException("1"); };
Runnable close2 = () -> { holder[1] = true; throw new RuntimeException("2"); };
Runnable close3 = () -> { holder[2] = true; throw new RuntimeException("3"); };
try (Stream<Integer> ints = countTo(100).stream()) {
ints.onClose(close1).onClose(close2).onClose(close3);
ints.forEach(i -> {});
}
catch (RuntimeException e) {
assertCascaded(e, 3);
assertTrue(holder[0] && holder[1] && holder[2]);
caught = true;
}
assertTrue(caught);
Arrays.fill(holder, false);
caught = false;
try (Stream<Integer> ints = countTo(100).stream().onClose(close1).onClose(close2).onClose(close3)) {
ints.forEach(i -> {});
}
catch (RuntimeException e) {
assertCascaded(e, 3);
assertTrue(holder[0] && holder[1] && holder[2]);
caught = true;
}
assertTrue(caught);
caught = false;
Arrays.fill(holder, false);
try (Stream<Integer> ints = countTo(100).stream().filter(e -> true).onClose(close1).onClose(close2).onClose(close3)) {
ints.forEach(i -> {});
}
catch (RuntimeException e) {
assertCascaded(e, 3);
assertTrue(holder[0] && holder[1] && holder[2]);
caught = true;
}
assertTrue(caught);
caught = false;
Arrays.fill(holder, false);
try (Stream<Integer> ints = countTo(100).stream().filter(e -> true).onClose(close1).onClose(close2).filter(e -> true).onClose(close3)) {
ints.forEach(i -> {});
}
catch (RuntimeException e) {
assertCascaded(e, 3);
assertTrue(holder[0] && holder[1] && holder[2]);
caught = true;
}
assertTrue(caught);
}
private void assertCascaded(RuntimeException e, int n) {
assertTrue(e.getMessage().equals("1"));
assertTrue(e.getSuppressed().length == n - 1);
for (int i=0; i<n-1; i++)
assertTrue(e.getSuppressed()[i].getMessage().equals(String.valueOf(i + 2)));
}
public void testConsumed() {
try(Stream<Integer> s = countTo(100).stream()) {
s.forEach(i -> {});
// Adding onClose handler when stream is consumed is illegal
// handler must not be registered
checkISE(() -> s.onClose(() -> fail("1")));
}
// close() must be idempotent:
// second close() invoked at the end of try-with-resources must have no effect
try(Stream<Integer> s = countTo(100).stream()) {
s.close();
// Adding onClose handler when stream is closed is also illegal
checkISE(() -> s.onClose(() -> fail("3")));
}
}
}

View file

@ -0,0 +1,104 @@
/*
* Copyright (c) 2012, 2013, 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.
*/
package org.openjdk.tests.java.util.stream;
import java.util.stream.*;
import org.testng.annotations.Test;
import java.util.Arrays;
import java.util.List;
import java.util.function.Function;
@Test
public class StreamLinkTest extends OpTestCase {
private <S> Function<S, S> apply(int n, Function<S, S> f) {
return s -> {
for (int i = 0; i < n; i++) {
s = f.apply(s);
}
return s;
};
}
private List<Integer> sizes = Arrays.asList(0, 1, 2, 3, 4, 5, 255, 1000);
@Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
public void testManyStreams(String name, TestData.OfRef<Integer> data) {
for (int n : sizes) {
setContext("n", n);
List<Integer> expected = data.stream().map(e -> (Integer) (e + n)).collect(Collectors.toList());
withData(data).
stream(apply(n, (Stream<Integer> s) -> s.map(e -> (Integer) (e + 1)))).
expectedResult(expected).
exercise();
}
}
@Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
public void testIntManyStreams(String name, TestData.OfInt data) {
for (int n : sizes) {
setContext("n", n);
int[] expected = data.stream().map(e -> e + n).toArray();
withData(data).
stream(apply(n, (IntStream s) -> s.map(e -> e + 1))).
expectedResult(expected).
exercise();
}
}
@Test(dataProvider = "LongStreamTestData", dataProviderClass = LongStreamTestDataProvider.class)
public void testLongManyStreams(String name, TestData.OfLong data) {
for (int n : sizes) {
setContext("n", n);
long[] expected = data.stream().map(e -> e + n).toArray();
withData(data).
stream(apply(n, (LongStream s) -> s.map(e -> e + 1L))).
expectedResult(expected).
exercise();
}
}
@Test(dataProvider = "DoubleStreamTestData", dataProviderClass = DoubleStreamTestDataProvider.class)
public void testDoubleManyStreams(String name, TestData.OfDouble data) {
for (int n : sizes) {
setContext("n", n);
double[] expected = data.stream().map(e -> accumulate(e, n)).toArray();
withData(data).
stream(apply(n, (DoubleStream s) -> s.map(e -> e + 1.0))).
expectedResult(expected).
exercise();
}
}
private double accumulate(double e, int n) {
while (n-- > 0) {
e = e + 1.0;
}
return e;
}
}

View file

@ -0,0 +1,52 @@
/*
* Copyright (c) 2013, 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.
*/
package org.openjdk.tests.java.util.stream;
import org.testng.annotations.Test;
import java.util.Arrays;
import java.util.stream.Stream;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertTrue;
@Test
public class StreamParSeqTest {
public void testParSeq() {
Stream<Integer> s = Arrays.asList(1, 2, 3, 4).stream().parallel();
assertTrue(s.isParallel());
s = s.sequential();
assertFalse(s.isParallel());
s = s.sequential();
assertFalse(s.isParallel());
s = s.parallel();
assertTrue(s.isParallel());
s = s.parallel();
assertTrue(s.isParallel());
}
}

View file

@ -0,0 +1,643 @@
/*
* Copyright (c) 2012, 2024, 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 8148838
*/
package org.openjdk.tests.java.util.stream;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Spliterator;
import java.util.SpliteratorTestHelper;
import java.util.function.Consumer;
import java.util.function.DoubleConsumer;
import java.util.function.Function;
import java.util.function.IntConsumer;
import java.util.function.LongConsumer;
import java.util.function.UnaryOperator;
import java.util.stream.DoubleStream;
import java.util.stream.DoubleStreamTestDataProvider;
import java.util.stream.IntStream;
import java.util.stream.IntStreamTestDataProvider;
import java.util.stream.LambdaTestHelpers;
import java.util.stream.LongStream;
import java.util.stream.LongStreamTestDataProvider;
import java.util.stream.OpTestCase;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
import java.util.stream.StreamTestDataProvider;
import java.util.stream.TestData;
import org.testng.Assert;
import org.testng.annotations.Test;
import static java.util.stream.LambdaTestHelpers.countTo;
import static java.util.stream.LambdaTestHelpers.dpEven;
import static java.util.stream.LambdaTestHelpers.ipEven;
import static java.util.stream.LambdaTestHelpers.irDoubler;
import static java.util.stream.LambdaTestHelpers.lpEven;
import static java.util.stream.LambdaTestHelpers.mDoubler;
import static java.util.stream.LambdaTestHelpers.pEven;
import static java.util.stream.LambdaTestHelpers.permuteStreamFunctions;
@Test
public class StreamSpliteratorTest extends OpTestCase {
private static class ProxyNoExactSizeSpliterator<T> implements Spliterator<T> {
final Spliterator<T> sp;
final boolean proxyEstimateSize;
int splits = 0;
int prefixSplits = 0;
long sizeOnTraversal = -1;
ProxyNoExactSizeSpliterator(Spliterator<T> sp, boolean proxyEstimateSize) {
this.sp = sp;
this.proxyEstimateSize = proxyEstimateSize;
}
@Override
public Spliterator<T> trySplit() {
splits++;
Spliterator<T> prefix = sp.trySplit();
if (prefix != null)
prefixSplits++;
return prefix;
}
@Override
public boolean tryAdvance(Consumer<? super T> consumer) {
if (sizeOnTraversal == -1)
sizeOnTraversal = sp.getExactSizeIfKnown();
return sp.tryAdvance(consumer);
}
@Override
public void forEachRemaining(Consumer<? super T> consumer) {
sizeOnTraversal = sp.getExactSizeIfKnown();
sp.forEachRemaining(consumer);
}
@Override
public long estimateSize() {
return proxyEstimateSize ? sp.estimateSize() : Long.MAX_VALUE;
}
@Override
public Comparator<? super T> getComparator() {
return sp.getComparator();
}
@Override
public int characteristics() {
if (proxyEstimateSize)
return sp.characteristics();
else
return sp.characteristics() & ~(Spliterator.SUBSIZED | Spliterator.SIZED);
}
private static class OfInt extends ProxyNoExactSizeSpliterator<Integer> implements Spliterator.OfInt {
final Spliterator.OfInt psp;
private OfInt(Spliterator.OfInt sp, boolean proxyEstimateSize) {
super(sp, proxyEstimateSize);
this.psp = sp;
}
@Override
public Spliterator.OfInt trySplit() {
splits++;
Spliterator.OfInt prefix = psp.trySplit();
if (prefix != null)
prefixSplits++;
return prefix;
}
@Override
public boolean tryAdvance(Consumer<? super Integer> consumer) {
return Spliterator.OfInt.super.tryAdvance(consumer);
}
@Override
public void forEachRemaining(Consumer<? super Integer> consumer) {
Spliterator.OfInt.super.forEachRemaining(consumer);
}
@Override
public boolean tryAdvance(IntConsumer consumer) {
if (sizeOnTraversal == -1)
sizeOnTraversal = sp.getExactSizeIfKnown();
return psp.tryAdvance(consumer);
}
@Override
public void forEachRemaining(IntConsumer consumer) {
sizeOnTraversal = sp.getExactSizeIfKnown();
psp.forEachRemaining(consumer);
}
}
private static class OfLong extends ProxyNoExactSizeSpliterator<Long> implements Spliterator.OfLong {
final Spliterator.OfLong psp;
private OfLong(Spliterator.OfLong sp, boolean proxyEstimateSize) {
super(sp, proxyEstimateSize);
this.psp = sp;
}
@Override
public Spliterator.OfLong trySplit() {
splits++;
Spliterator.OfLong prefix = psp.trySplit();
if (prefix != null)
prefixSplits++;
return prefix;
}
@Override
public boolean tryAdvance(Consumer<? super Long> consumer) {
return Spliterator.OfLong.super.tryAdvance(consumer);
}
@Override
public void forEachRemaining(Consumer<? super Long> consumer) {
Spliterator.OfLong.super.forEachRemaining(consumer);
}
@Override
public boolean tryAdvance(LongConsumer consumer) {
if (sizeOnTraversal == -1)
sizeOnTraversal = sp.getExactSizeIfKnown();
return psp.tryAdvance(consumer);
}
@Override
public void forEachRemaining(LongConsumer consumer) {
sizeOnTraversal = sp.getExactSizeIfKnown();
psp.forEachRemaining(consumer);
}
}
private static class OfDouble extends ProxyNoExactSizeSpliterator<Double>
implements Spliterator.OfDouble {
final Spliterator.OfDouble psp;
private OfDouble(Spliterator.OfDouble sp, boolean proxyEstimateSize) {
super(sp, proxyEstimateSize);
this.psp = sp;
}
@Override
public Spliterator.OfDouble trySplit() {
splits++;
Spliterator.OfDouble prefix = psp.trySplit();
if (prefix != null)
prefixSplits++;
return prefix;
}
@Override
public boolean tryAdvance(Consumer<? super Double> consumer) {
return Spliterator.OfDouble.super.tryAdvance(consumer);
}
@Override
public void forEachRemaining(Consumer<? super Double> consumer) {
Spliterator.OfDouble.super.forEachRemaining(consumer);
}
@Override
public boolean tryAdvance(DoubleConsumer consumer) {
if (sizeOnTraversal == -1)
sizeOnTraversal = sp.getExactSizeIfKnown();
return psp.tryAdvance(consumer);
}
@Override
public void forEachRemaining(DoubleConsumer consumer) {
sizeOnTraversal = sp.getExactSizeIfKnown();
psp.forEachRemaining(consumer);
}
}
}
public void testSplitting() {
// Size is assumed to be larger than the target size for no splitting
// @@@ Need way to obtain the target size
List<Integer> l = countTo(1000);
List<Consumer<Stream<Integer>>> terminalOps = Arrays.asList(
s -> s.toArray(),
s -> s.forEach(e -> { }),
s -> s.reduce(Integer::sum)
);
List<UnaryOperator<Stream<Integer>>> intermediateOps = Arrays.asList(
s -> s.parallel(),
// The following ensures the wrapping spliterator is tested
s -> s.map(LambdaTestHelpers.identity()).parallel()
);
for (int i = 0; i < terminalOps.size(); i++) {
setContext("termOpIndex", i);
Consumer<Stream<Integer>> terminalOp = terminalOps.get(i);
for (int j = 0; j < intermediateOps.size(); j++) {
setContext("intOpIndex", j);
UnaryOperator<Stream<Integer>> intermediateOp = intermediateOps.get(j);
for (boolean proxyEstimateSize : new boolean[] {false, true}) {
setContext("proxyEstimateSize", proxyEstimateSize);
Spliterator<Integer> sp = intermediateOp.apply(l.stream()).spliterator();
ProxyNoExactSizeSpliterator<Integer> psp = new ProxyNoExactSizeSpliterator<>(sp, proxyEstimateSize);
Stream<Integer> s = StreamSupport.stream(psp, true);
terminalOp.accept(s);
Assert.assertTrue(psp.splits > 0,
String.format("Number of splits should be greater that zero when proxyEstimateSize is %s",
proxyEstimateSize));
Assert.assertTrue(psp.prefixSplits > 0,
String.format("Number of non-null prefix splits should be greater that zero when proxyEstimateSize is %s",
proxyEstimateSize));
Assert.assertTrue(psp.sizeOnTraversal < l.size(),
String.format("Size on traversal of last split should be less than the size of the list, %d, when proxyEstimateSize is %s",
l.size(), proxyEstimateSize));
}
}
}
}
@Test(dataProvider = "StreamTestData<Integer>.small",
dataProviderClass = StreamTestDataProvider.class,
groups = { "serialization-hostile" })
public void testStreamSpliterators(String name, TestData.OfRef<Integer> data) {
for (Function<Stream<Integer>, Stream<Integer>> f : streamFunctions()) {
withData(data).
stream((Stream<Integer> in) -> {
Stream<Integer> out = f.apply(in);
return StreamSupport.stream(() -> out.spliterator(), OpTestCase.getStreamFlags(out), false);
}).
exercise();
withData(data).
stream((Stream<Integer> in) -> {
Stream<Integer> out = f.apply(in);
return StreamSupport.stream(() -> out.spliterator(), OpTestCase.getStreamFlags(out), true);
}).
exercise();
}
}
@Test(dataProvider = "StreamTestData<Integer>.small", dataProviderClass = StreamTestDataProvider.class)
public void testSpliterators(String name, TestData.OfRef<Integer> data) {
for (Function<Stream<Integer>, Stream<Integer>> f : streamFunctions()) {
SpliteratorTestHelper.testSpliterator(() -> f.apply(data.stream()).spliterator());
}
}
@Test(dataProvider = "StreamTestData<Integer>.small", dataProviderClass = StreamTestDataProvider.class)
public void testParSpliterators(String name, TestData.OfRef<Integer> data) {
for (Function<Stream<Integer>, Stream<Integer>> f : streamFunctions()) {
SpliteratorTestHelper.testSpliterator(() -> f.apply(data.parallelStream()).spliterator());
}
}
private List<Function<Stream<Integer>, Stream<Integer>>> streamFunctions;
List<Function<Stream<Integer>, Stream<Integer>>> streamFunctions() {
if (streamFunctions == null) {
List<Function<Stream<Integer>, Stream<Integer>>> opFunctions = Arrays.asList(
s -> s.filter(pEven),
s -> s.flatMap(x -> Stream.of(x, x)),
// @@@ Add distinct once asserting results with or without order
// is correctly supported
// s -> s.distinct(),
s -> s.sorted());
streamFunctions = permuteStreamFunctions(opFunctions);
}
return streamFunctions;
}
//
public void testIntSplitting() {
List<Consumer<IntStream>> terminalOps = Arrays.asList(
s -> s.toArray(),
s -> s.forEach(e -> {}),
s -> s.reduce(Integer::sum)
);
List<UnaryOperator<IntStream>> intermediateOps = Arrays.asList(
s -> s.parallel(),
// The following ensures the wrapping spliterator is tested
s -> s.map(i -> i).parallel()
);
for (int i = 0; i < terminalOps.size(); i++) {
setContext("termOpIndex", i);
Consumer<IntStream> terminalOp = terminalOps.get(i);
for (int j = 0; j < intermediateOps.size(); j++) {
setContext("intOpIndex", j);
UnaryOperator<IntStream> intermediateOp = intermediateOps.get(j);
for (boolean proxyEstimateSize : new boolean[] {false, true}) {
setContext("proxyEstimateSize", proxyEstimateSize);
// Size is assumed to be larger than the target size for no splitting
// @@@ Need way to obtain the target size
Spliterator.OfInt sp = intermediateOp.apply(IntStream.range(0, 1000)).spliterator();
ProxyNoExactSizeSpliterator.OfInt psp = new ProxyNoExactSizeSpliterator.OfInt(sp, proxyEstimateSize);
IntStream s = StreamSupport.intStream(psp, true);
terminalOp.accept(s);
Assert.assertTrue(psp.splits > 0,
String.format("Number of splits should be greater that zero when proxyEstimateSize is %s",
proxyEstimateSize));
Assert.assertTrue(psp.prefixSplits > 0,
String.format("Number of non-null prefix splits should be greater that zero when proxyEstimateSize is %s",
proxyEstimateSize));
Assert.assertTrue(psp.sizeOnTraversal < 1000,
String.format("Size on traversal of last split should be less than the size of the list, %d, when proxyEstimateSize is %s",
1000, proxyEstimateSize));
}
}
}
}
@Test(dataProvider = "IntStreamTestData.small",
dataProviderClass = IntStreamTestDataProvider.class,
groups = { "serialization-hostile" })
public void testIntStreamSpliterators(String name, TestData.OfInt data) {
for (Function<IntStream, IntStream> f : intStreamFunctions()) {
withData(data).
stream(in -> {
IntStream out = f.apply(in);
return StreamSupport.intStream(() -> out.spliterator(), OpTestCase.getStreamFlags(out), false);
}).
exercise();
withData(data).
stream((in) -> {
IntStream out = f.apply(in);
return StreamSupport.intStream(() -> out.spliterator(), OpTestCase.getStreamFlags(out), true);
}).
exercise();
}
}
@Test(dataProvider = "IntStreamTestData.small", dataProviderClass = IntStreamTestDataProvider.class)
public void testIntSpliterators(String name, TestData.OfInt data) {
for (Function<IntStream, IntStream> f : intStreamFunctions()) {
SpliteratorTestHelper.testIntSpliterator(() -> f.apply(data.stream()).spliterator());
}
}
@Test(dataProvider = "IntStreamTestData.small", dataProviderClass = IntStreamTestDataProvider.class)
public void testIntParSpliterators(String name, TestData.OfInt data) {
for (Function<IntStream, IntStream> f : intStreamFunctions()) {
SpliteratorTestHelper.testIntSpliterator(() -> f.apply(data.parallelStream()).spliterator());
}
}
private List<Function<IntStream, IntStream>> intStreamFunctions;
List<Function<IntStream, IntStream>> intStreamFunctions() {
if (intStreamFunctions == null) {
List<Function<IntStream, IntStream>> opFunctions = Arrays.asList(
s -> s.filter(ipEven),
s -> s.flatMap(x -> IntStream.of(x, x)),
s -> s.sorted());
intStreamFunctions = permuteStreamFunctions(opFunctions);
}
return intStreamFunctions;
}
//
public void testLongSplitting() {
List<Consumer<LongStream>> terminalOps = Arrays.asList(
s -> s.toArray(),
s -> s.forEach(e -> {}),
s -> s.reduce(Long::sum)
);
List<UnaryOperator<LongStream>> intermediateOps = Arrays.asList(
s -> s.parallel(),
// The following ensures the wrapping spliterator is tested
s -> s.map(i -> i).parallel()
);
for (int i = 0; i < terminalOps.size(); i++) {
Consumer<LongStream> terminalOp = terminalOps.get(i);
setContext("termOpIndex", i);
for (int j = 0; j < intermediateOps.size(); j++) {
setContext("intOpIndex", j);
UnaryOperator<LongStream> intermediateOp = intermediateOps.get(j);
for (boolean proxyEstimateSize : new boolean[] {false, true}) {
setContext("proxyEstimateSize", proxyEstimateSize);
// Size is assumed to be larger than the target size for no splitting
// @@@ Need way to obtain the target size
Spliterator.OfLong sp = intermediateOp.apply(LongStream.range(0, 1000)).spliterator();
ProxyNoExactSizeSpliterator.OfLong psp = new ProxyNoExactSizeSpliterator.OfLong(sp, proxyEstimateSize);
LongStream s = StreamSupport.longStream(psp, true);
terminalOp.accept(s);
Assert.assertTrue(psp.splits > 0,
String.format("Number of splits should be greater that zero when proxyEstimateSize is %s",
proxyEstimateSize));
Assert.assertTrue(psp.prefixSplits > 0,
String.format("Number of non-null prefix splits should be greater that zero when proxyEstimateSize is %s",
proxyEstimateSize));
Assert.assertTrue(psp.sizeOnTraversal < 1000,
String.format("Size on traversal of last split should be less than the size of the list, %d, when proxyEstimateSize is %s",
1000, proxyEstimateSize));
}
}
}
}
@Test(dataProvider = "LongStreamTestData.small",
dataProviderClass = LongStreamTestDataProvider.class,
groups = { "serialization-hostile" })
public void testLongStreamSpliterators(String name, TestData.OfLong data) {
for (Function<LongStream, LongStream> f : longStreamFunctions()) {
withData(data).
stream(in -> {
LongStream out = f.apply(in);
return StreamSupport.longStream(() -> out.spliterator(), OpTestCase.getStreamFlags(out), false);
}).
exercise();
withData(data).
stream((in) -> {
LongStream out = f.apply(in);
return StreamSupport.longStream(() -> out.spliterator(), OpTestCase.getStreamFlags(out), true);
}).
exercise();
}
}
@Test(dataProvider = "LongStreamTestData.small", dataProviderClass = LongStreamTestDataProvider.class)
public void testLongSpliterators(String name, TestData.OfLong data) {
for (Function<LongStream, LongStream> f : longStreamFunctions()) {
SpliteratorTestHelper.testLongSpliterator(() -> f.apply(data.stream()).spliterator());
}
}
@Test(dataProvider = "LongStreamTestData.small", dataProviderClass = LongStreamTestDataProvider.class)
public void testLongParSpliterators(String name, TestData.OfLong data) {
for (Function<LongStream, LongStream> f : longStreamFunctions()) {
SpliteratorTestHelper.testLongSpliterator(() -> f.apply(data.parallelStream()).spliterator());
}
}
private List<Function<LongStream, LongStream>> longStreamFunctions;
List<Function<LongStream, LongStream>> longStreamFunctions() {
if (longStreamFunctions == null) {
List<Function<LongStream, LongStream>> opFunctions = Arrays.asList(
s -> s.filter(lpEven),
s -> s.flatMap(x -> LongStream.of(x, x)),
s -> s.sorted());
longStreamFunctions = permuteStreamFunctions(opFunctions);
}
return longStreamFunctions;
}
//
public void testDoubleSplitting() {
List<Consumer<DoubleStream>> terminalOps = Arrays.asList(
s -> s.toArray(),
s -> s.forEach(e -> {}),
s -> s.reduce(Double::sum)
);
List<UnaryOperator<DoubleStream>> intermediateOps = Arrays.asList(
s -> s.parallel(),
// The following ensures the wrapping spliterator is tested
s -> s.map(i -> i).parallel()
);
for (int i = 0; i < terminalOps.size(); i++) {
Consumer<DoubleStream> terminalOp = terminalOps.get(i);
setContext("termOpIndex", i);
for (int j = 0; j < intermediateOps.size(); j++) {
UnaryOperator<DoubleStream> intermediateOp = intermediateOps.get(j);
setContext("intOpIndex", j);
for (boolean proxyEstimateSize : new boolean[] {false, true}) {
setContext("proxyEstimateSize", proxyEstimateSize);
// Size is assumed to be larger than the target size for no splitting
// @@@ Need way to obtain the target size
Spliterator.OfDouble sp = intermediateOp.apply(IntStream.range(0, 1000).asDoubleStream()).spliterator();
ProxyNoExactSizeSpliterator.OfDouble psp = new ProxyNoExactSizeSpliterator.OfDouble(sp, proxyEstimateSize);
DoubleStream s = StreamSupport.doubleStream(psp, true);
terminalOp.accept(s);
Assert.assertTrue(psp.splits > 0,
String.format("Number of splits should be greater that zero when proxyEstimateSize is %s",
proxyEstimateSize));
Assert.assertTrue(psp.prefixSplits > 0,
String.format("Number of non-null prefix splits should be greater that zero when proxyEstimateSize is %s",
proxyEstimateSize));
Assert.assertTrue(psp.sizeOnTraversal < 1000,
String.format("Size on traversal of last split should be less than the size of the list, %d, when proxyEstimateSize is %s",
1000, proxyEstimateSize));
}
}
}
}
@Test(dataProvider = "DoubleStreamTestData.small",
dataProviderClass = DoubleStreamTestDataProvider.class,
groups = { "serialization-hostile" })
public void testDoubleStreamSpliterators(String name, TestData.OfDouble data) {
for (Function<DoubleStream, DoubleStream> f : doubleStreamFunctions()) {
withData(data).
stream(in -> {
DoubleStream out = f.apply(in);
return StreamSupport.doubleStream(() -> out.spliterator(), OpTestCase.getStreamFlags(out), false);
}).
exercise();
withData(data).
stream((in) -> {
DoubleStream out = f.apply(in);
return StreamSupport.doubleStream(() -> out.spliterator(), OpTestCase.getStreamFlags(out), true);
}).
exercise();
}
}
@Test(dataProvider = "DoubleStreamTestData.small", dataProviderClass = DoubleStreamTestDataProvider.class)
public void testDoubleSpliterators(String name, TestData.OfDouble data) {
for (Function<DoubleStream, DoubleStream> f : doubleStreamFunctions()) {
SpliteratorTestHelper.testDoubleSpliterator(() -> f.apply(data.stream()).spliterator());
}
}
@Test(dataProvider = "DoubleStreamTestData.small", dataProviderClass = DoubleStreamTestDataProvider.class)
public void testDoubleParSpliterators(String name, TestData.OfDouble data) {
for (Function<DoubleStream, DoubleStream> f : doubleStreamFunctions()) {
SpliteratorTestHelper.testDoubleSpliterator(() -> f.apply(data.parallelStream()).spliterator());
}
}
@Test
public void testCharacteristicsForSortedUnorderedStreamSpliterators() {
assertValidCombinationOfSortedAndOrdered(
DoubleStream.of(3d,2d,4d,1d,5d).sorted().unordered().spliterator()
);
assertValidCombinationOfSortedAndOrdered(
IntStream.of(3,2,4,1,5).sorted().unordered().spliterator()
);
assertValidCombinationOfSortedAndOrdered(
LongStream.of(3L,2L,4L,1L,5L).sorted().unordered().spliterator()
);
assertValidCombinationOfSortedAndOrdered(
Stream.of(3,2,4,1,5).sorted().unordered().spliterator()
);
}
void assertValidCombinationOfSortedAndOrdered(Spliterator<?> s) {
if (s.hasCharacteristics(Spliterator.SORTED))
Assert.assertTrue(s.hasCharacteristics(Spliterator.ORDERED));
}
private List<Function<DoubleStream, DoubleStream>> doubleStreamFunctions;
List<Function<DoubleStream, DoubleStream>> doubleStreamFunctions() {
if (doubleStreamFunctions == null) {
List<Function<DoubleStream, DoubleStream>> opFunctions = Arrays.asList(
s -> s.filter(dpEven),
s -> s.flatMap(x -> DoubleStream.of(x, x)),
s -> s.sorted());
doubleStreamFunctions = permuteStreamFunctions(opFunctions);
}
return doubleStreamFunctions;
}
}

View file

@ -0,0 +1 @@
timeout.default.seconds=480

View file

@ -0,0 +1,139 @@
/*
* Copyright (c) 2012, 2013, 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.
*/
package org.openjdk.tests.java.util.stream;
import java.util.function.Consumer;
import java.util.function.DoubleConsumer;
import java.util.function.IntConsumer;
import java.util.function.LongConsumer;
import java.util.stream.*;
import org.testng.annotations.Test;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import static java.util.stream.LambdaTestHelpers.*;
/**
* TeeOpTest
*/
@Test(groups = { "serialization-hostile" })
public class TeeOpTest extends OpTestCase {
public void testTee() {
List<Integer> copy = new ArrayList<>();
assertCountSum(countTo(0).stream().peek(copy::add), 0, 0);
assertCountSum(copy.iterator(), 0, 0);
copy.clear();
assertCountSum(countTo(10).stream().peek(copy::add), 10, 55);
assertCountSum(copy.iterator(), 10, 55);
copy.clear();
assertCountSum(countTo(10).stream().map(mDoubler).peek(copy::add), 10, 110);
assertCountSum(copy.iterator(), 10, 110);
}
static class AbstractRecordingConsumer<T> {
List<T> list;
void before(TestData<T, ?> td) {
// Tee block can be called concurrently
list = Collections.synchronizedList(new ArrayList<>());
}
void after(TestData<T, ?> td) {
// No guarantees in parallel tests that calls to tee block will
// be in the encounter order, if defined, of the data
// @@@ Consider passing more meta-data about evaluation
assertContentsUnordered(list, td.into(new ArrayList<T>()));
}
}
@Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
public void testOps(String name, final TestData.OfRef<Integer> data) {
class RecordingConsumer extends AbstractRecordingConsumer<Integer> implements Consumer<Integer> {
public void accept(Integer t) {
list.add(t);
}
}
final RecordingConsumer b = new RecordingConsumer();
withData(data)
.stream(s -> s.peek(b))
.before(b::before)
.after(b::after)
.exercise();
}
@Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
public void testIntOps(String name, final TestData.OfInt data) {
class RecordingConsumer extends AbstractRecordingConsumer<Integer> implements IntConsumer {
public void accept(int t) {
list.add(t);
}
}
final RecordingConsumer b = new RecordingConsumer();
withData(data)
.stream(s -> s.peek(b))
.before(b::before)
.after(b::after)
.exercise();
}
@Test(dataProvider = "LongStreamTestData", dataProviderClass = LongStreamTestDataProvider.class)
public void testLongOps(String name, final TestData.OfLong data) {
class RecordingConsumer extends AbstractRecordingConsumer<Long> implements LongConsumer {
public void accept(long t) {
list.add(t);
}
}
final RecordingConsumer b = new RecordingConsumer();
withData(data)
.stream(s -> s.peek(b))
.before(b::before)
.after(b::after)
.exercise();
}
@Test(dataProvider = "DoubleStreamTestData", dataProviderClass = DoubleStreamTestDataProvider.class)
public void testDoubleOps(String name, final TestData.OfDouble data) {
class RecordingConsumer extends AbstractRecordingConsumer<Double> implements DoubleConsumer {
public void accept(double t) {
list.add(t);
}
}
final RecordingConsumer b = new RecordingConsumer();
withData(data)
.stream(s -> s.peek(b))
.before(b::before)
.after(b::after)
.exercise();
}
}

View file

@ -0,0 +1,417 @@
/*
* Copyright (c) 2012, 2013, 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.
*/
package org.openjdk.tests.java.util.stream;
import org.testng.annotations.Test;
import java.util.*;
import java.util.function.Function;
import java.util.stream.*;
import static java.util.stream.LambdaTestHelpers.*;
import static org.testng.Assert.assertEquals;
/**
* ToArrayOpTest
*
*/
@Test
public class ToArrayOpTest extends OpTestCase {
public void testToArray() {
assertCountSum(Arrays.asList(countTo(0).stream().toArray()), 0, 0);
assertCountSum(Arrays.asList(countTo(10).stream().toArray()), 10, 55);
}
@Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
public void testOps(String name, TestData.OfRef<Integer> data) {
exerciseTerminalOps(data, s -> s.toArray());
}
@Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
public void testOpsWithMap(String name, TestData.OfRef<Integer> data) {
// Retain the size of the source
// This should kick in the parallel evaluation optimization for tasks stuffing elements into a shared array
Object[] objects = exerciseTerminalOps(data, s -> s.map(i -> (Integer) (i + i)), s -> s.toArray());
assertTrue(objects.length == data.size());
}
@Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
public void testOpsWithSorted(String name, TestData.OfRef<Integer> data) {
// Retain the size of the source
// This should kick in the parallel evaluation optimization for tasks stuffing elements into a shared array
Object[] objects = exerciseTerminalOps(data, s -> s.sorted(), s -> s.toArray());
assertTrue(objects.length == data.size());
}
@Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
public void testOpsWithFlatMap(String name, TestData.OfRef<Integer> data) {
// Double the size of the source
// Fixed size optimizations will not be used
Object[] objects = exerciseTerminalOps(data,
s -> s.flatMap(e -> Arrays.stream(new Object[] { e, e })),
s -> s.toArray());
assertTrue(objects.length == data.size() * 2);
}
@Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
public void testOpsWithFilter(String name, TestData.OfRef<Integer> data) {
// Reduce the size of the source
// Fixed size optimizations will not be used
exerciseTerminalOps(data, s -> s.filter(LambdaTestHelpers.pEven), s -> s.toArray());
}
public void testAsArrayWithType() {
exerciseTerminalOps(
TestData.Factory.ofCollection("", Arrays.asList(1.1, 2.2, 3.4, 4.4)),
s -> // First pipeline slice using Object[] with Double elements
s.sorted()
// Second pipeline slice using Integer[] with Integer elements
.map((Double d) -> Integer.valueOf(d.intValue())).sorted(),
s -> s.toArray(Integer[]::new));
}
private List<Function<Stream<Integer>, Stream<Integer>>> uniqueAndSortedPermutations =
LambdaTestHelpers.permuteStreamFunctions(Arrays.asList(
s -> s.distinct(),
s -> s.distinct(),
s -> s.sorted(),
s -> s.sorted()
));
@Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
public void testDistinctAndSortedPermutations(String name, TestData.OfRef<Integer> data) {
for (Function<Stream<Integer>, Stream<Integer>> f : uniqueAndSortedPermutations) {
exerciseTerminalOps(data, f, s -> s.toArray());
Integer[] is = exerciseTerminalOps(data, f, s -> s.toArray(Integer[]::new));
assertEquals(is.getClass(), Integer[].class);
Number[] ns = exerciseTerminalOps(data, f, s -> s.toArray(Number[]::new));
assertEquals(ns.getClass(), Number[].class);
if (data.size() > 0) {
Exception caught = null;
try {
exerciseTerminalOps(data, f, s -> s.toArray(String[]::new));
} catch (Exception e) {
caught = e;
}
assertTrue(caught != null);
assertEquals(caught.getClass(), ArrayStoreException.class);
}
}
}
private List<Function<Stream<Integer>, Stream<Integer>>> statefulOpPermutations =
LambdaTestHelpers.permuteStreamFunctions(Arrays.asList(
s -> s.limit(10),
s -> s.distinct(),
s -> s.sorted()
));
private <T extends Object> ResultAsserter<T[]> statefulOpResultAsserter(TestData.OfRef<Integer> data) {
return (act, exp, ord, par) -> {
if (par) {
if (!data.isOrdered()) {
// Relax the checking if the data source is unordered
// It is not exactly possible to determine if the limit
// operation is present and if it is before or after
// the sorted operation
// If the limit operation is present and before the sorted
// operation then the sub-set output after limit is a
// non-deterministic sub-set of the source
List<Integer> expected = new ArrayList<>();
data.forEach(expected::add);
List<T> actual = Arrays.asList(act);
assertEquals(actual.size(), exp.length);
assertTrue(expected.containsAll(actual));
return;
}
else if (!ord) {
LambdaTestHelpers.assertContentsUnordered(Arrays.asList(act),
Arrays.asList(exp));
return;
}
}
assertEquals(act, exp);
};
}
@Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class,
groups = { "serialization-hostile" })
public void testStatefulOpPermutations(String name, TestData.OfRef<Integer> data) {
for (Function<Stream<Integer>, Stream<Integer>> f : statefulOpPermutations) {
withData(data).terminal(f, s -> s.toArray())
.resultAsserter(statefulOpResultAsserter(data))
.exercise();
Integer[] is = withData(data).terminal(f, s -> s.toArray(Integer[]::new))
.resultAsserter(statefulOpResultAsserter(data))
.exercise();
assertEquals(is.getClass(), Integer[].class);
Number[] ns = withData(data).terminal(f, s -> s.toArray(Number[]::new))
.resultAsserter(statefulOpResultAsserter(data))
.exercise();
assertEquals(ns.getClass(), Number[].class);
if (data.size() > 0) {
Exception caught = null;
try {
exerciseTerminalOps(data, f, s -> s.toArray(String[]::new));
} catch (Exception e) {
caught = e;
}
assertTrue(caught != null);
assertEquals(caught.getClass(), ArrayStoreException.class);
}
}
}
//
@Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
public void testIntOps(String name, TestData.OfInt data) {
exerciseTerminalOps(data, s -> s.toArray());
}
@Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
public void testIntOpsWithMap(String name, TestData.OfInt data) {
// Retain the size of the source
// This should kick in the parallel evaluation optimization for tasks stuffing elements into a shared array
int[] ints = exerciseTerminalOps(data, s -> s.map(i -> i + i), s -> s.toArray());
assertTrue(ints.length == data.size());
}
@Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
public void testIntOpsWithSorted(String name, TestData.OfInt data) {
// Retain the size of the source
// This should kick in the parallel evaluation optimization for tasks stuffing elements into a shared array
int[] ints = exerciseTerminalOps(data, s -> s.sorted(), (IntStream s) -> s.toArray());
assertTrue(ints.length == data.size());
}
@Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
public void testIntOpsWithFlatMap(String name, TestData.OfInt data) {
// Int the size of the source
// Fixed size optimizations will not be used
int[] objects = exerciseTerminalOps(data,
s -> s.flatMap(e -> Arrays.stream(new int[] { e, e })),
s -> s.toArray());
assertTrue(objects.length == data.size() * 2);
}
@Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
public void testIntOpsWithFilter(String name, TestData.OfInt data) {
// Reduce the size of the source
// Fixed size optimizations will not be used
exerciseTerminalOps(data, s -> s.filter(LambdaTestHelpers.ipEven), s -> s.toArray());
}
private List<Function<IntStream, IntStream>> intUniqueAndSortedPermutations =
LambdaTestHelpers.permuteStreamFunctions(Arrays.asList(
s -> s.distinct(),
s -> s.distinct(),
s -> s.sorted(),
s -> s.sorted()
));
@Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
public void testIntDistinctAndSortedPermutations(String name, TestData.OfInt data) {
for (Function<IntStream, IntStream> f : intUniqueAndSortedPermutations) {
exerciseTerminalOps(data, f, s -> s.toArray());
}
}
private List<Function<IntStream, IntStream>> intStatefulOpPermutations =
LambdaTestHelpers.permuteStreamFunctions(Arrays.asList(
s -> s.limit(10),
s -> s.distinct(),
s -> s.sorted()
));
@Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
public void testIntStatefulOpPermutations(String name, TestData.OfInt data) {
for (Function<IntStream, IntStream> f : intStatefulOpPermutations) {
exerciseTerminalOps(data, f, s -> s.toArray());
}
}
//
@Test(dataProvider = "LongStreamTestData", dataProviderClass = LongStreamTestDataProvider.class)
public void testLongOps(String name, TestData.OfLong data) {
exerciseTerminalOps(data, s -> s.toArray());
}
@Test(dataProvider = "LongStreamTestData", dataProviderClass = LongStreamTestDataProvider.class)
public void testLongOpsWithMap(String name, TestData.OfLong data) {
// Retain the size of the source
// This should kick in the parallel evaluation optimization for tasks stuffing elements into a shared array
long[] longs = exerciseTerminalOps(data, s -> s.map(i -> i + i), s -> s.toArray());
assertTrue(longs.length == data.size());
}
@Test(dataProvider = "LongStreamTestData", dataProviderClass = LongStreamTestDataProvider.class)
public void testLongOpsWithSorted(String name, TestData.OfLong data) {
// Retain the size of the source
// This should kick in the parallel evaluation optimization for tasks stuffing elements into a shared array
long[] longs = exerciseTerminalOps(data, s -> s.sorted(), (LongStream s) -> s.toArray());
assertTrue(longs.length == data.size());
}
@Test(dataProvider = "LongStreamTestData", dataProviderClass = LongStreamTestDataProvider.class)
public void testLongOpsWithFlatMap(String name, TestData.OfLong data) {
// Long the size of the source
// Fixed size optimizations will not be used
long[] objects = exerciseTerminalOps(data,
s -> s.flatMap(e -> Arrays.stream(new long[] { e, e })),
s -> s.toArray());
assertTrue(objects.length == data.size() * 2);
}
@Test(dataProvider = "LongStreamTestData", dataProviderClass = LongStreamTestDataProvider.class)
public void testLongOpsWithFilter(String name, TestData.OfLong data) {
// Reduce the size of the source
// Fixed size optimizations will not be used
exerciseTerminalOps(data, s -> s.filter(LambdaTestHelpers.lpEven), s -> s.toArray());
}
private List<Function<LongStream, LongStream>> longUniqueAndSortedPermutations =
LambdaTestHelpers.permuteStreamFunctions(Arrays.asList(
s -> s.distinct(),
s -> s.distinct(),
s -> s.sorted(),
s -> s.sorted()
));
@Test(dataProvider = "LongStreamTestData", dataProviderClass = LongStreamTestDataProvider.class)
public void testLongDistinctAndSortedPermutations(String name, TestData.OfLong data) {
for (Function<LongStream, LongStream> f : longUniqueAndSortedPermutations) {
exerciseTerminalOps(data, f, s -> s.toArray());
}
}
private List<Function<LongStream, LongStream>> longStatefulOpPermutations =
LambdaTestHelpers.permuteStreamFunctions(Arrays.asList(
s -> s.limit(10),
s -> s.distinct(),
s -> s.sorted()
));
@Test(dataProvider = "LongStreamTestData", dataProviderClass = LongStreamTestDataProvider.class)
public void testLongStatefulOpPermutations(String name, TestData.OfLong data) {
for (Function<LongStream, LongStream> f : longStatefulOpPermutations) {
exerciseTerminalOps(data, f, s -> s.toArray());
}
}
//
@Test(dataProvider = "DoubleStreamTestData", dataProviderClass = DoubleStreamTestDataProvider.class)
public void testDoubleOps(String name, TestData.OfDouble data) {
exerciseTerminalOps(data, s -> s.toArray());
}
@Test(dataProvider = "DoubleStreamTestData", dataProviderClass = DoubleStreamTestDataProvider.class)
public void testDoubleOpsWithMap(String name, TestData.OfDouble data) {
// Retain the size of the source
// This should kick in the parallel evaluation optimization for tasks stuffing elements into a shared array
double[] doubles = exerciseTerminalOps(data, s -> s.map(i -> i + i), s -> s.toArray());
assertTrue(doubles.length == data.size());
}
@Test(dataProvider = "DoubleStreamTestData", dataProviderClass = DoubleStreamTestDataProvider.class)
public void testDoubleOpsWithSorted(String name, TestData.OfDouble data) {
// Retain the size of the source
// This should kick in the parallel evaluation optimization for tasks stuffing elements into a shared array
double[] doubles = exerciseTerminalOps(data, s -> s.sorted(), (DoubleStream s) -> s.toArray());
assertTrue(doubles.length == data.size());
}
@Test(dataProvider = "DoubleStreamTestData", dataProviderClass = DoubleStreamTestDataProvider.class)
public void testDoubleOpsWithFlatMap(String name, TestData.OfDouble data) {
// Double the size of the source
// Fixed size optimizations will not be used
double[] objects = exerciseTerminalOps(data,
s -> s.flatMap(e -> Arrays.stream(new double[] { e, e })),
s -> s.toArray());
assertTrue(objects.length == data.size() * 2);
}
@Test(dataProvider = "DoubleStreamTestData", dataProviderClass = DoubleStreamTestDataProvider.class)
public void testDoubleOpsWithFilter(String name, TestData.OfDouble data) {
// Reduce the size of the source
// Fixed size optimizations will not be used
exerciseTerminalOps(data, s -> s.filter(LambdaTestHelpers.dpEven), s -> s.toArray());
}
private List<Function<DoubleStream, DoubleStream>> doubleUniqueAndSortedPermutations =
LambdaTestHelpers.permuteStreamFunctions(Arrays.asList(
s -> s.distinct(),
s -> s.distinct(),
s -> s.sorted(),
s -> s.sorted()
));
@Test(dataProvider = "DoubleStreamTestData", dataProviderClass = DoubleStreamTestDataProvider.class)
public void testDoubleDistinctAndSortedPermutations(String name, TestData.OfDouble data) {
for (Function<DoubleStream, DoubleStream> f : doubleUniqueAndSortedPermutations) {
exerciseTerminalOps(data, f, s -> s.toArray());
}
}
private List<Function<DoubleStream, DoubleStream>> doubleStatefulOpPermutations =
LambdaTestHelpers.permuteStreamFunctions(Arrays.asList(
s -> s.limit(10),
s -> s.distinct(),
s -> s.sorted()
));
@Test(dataProvider = "DoubleStreamTestData", dataProviderClass = DoubleStreamTestDataProvider.class)
public void testDoubleStatefulOpPermutations(String name, TestData.OfDouble data) {
for (Function<DoubleStream, DoubleStream> f : doubleStatefulOpPermutations) {
exerciseTerminalOps(data, f, s -> s.toArray());
}
}
}

View file

@ -0,0 +1,89 @@
/*
* Copyright (c) 2020, 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.
*/
package org.openjdk.tests.java.util.stream;
import org.testng.annotations.Test;
import java.util.*;
import java.util.stream.*;
import static java.util.stream.LambdaTestHelpers.*;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertTrue;
/**
* ToListOpTest
*/
@Test
public class ToListOpTest extends OpTestCase {
public void testToList() {
assertCountSum(countTo(0).stream().toList(), 0, 0);
assertCountSum(countTo(10).stream().toList(), 10, 55);
}
private void checkUnmodifiable(List<Integer> list) {
try {
list.add(Integer.MIN_VALUE);
fail("List.add did not throw UnsupportedOperationException");
} catch (UnsupportedOperationException ignore) { }
if (list.size() > 0) {
try {
list.set(0, Integer.MAX_VALUE);
fail("List.set did not throw UnsupportedOperationException");
} catch (UnsupportedOperationException ignore) { }
}
}
@Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
public void testOps(String name, TestData.OfRef<Integer> data) {
List<Integer> objects = exerciseTerminalOps(data, s -> s.toList());
checkUnmodifiable(objects);
assertFalse(objects.contains(null));
}
@Test(dataProvider = "withNull:StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
public void testOpsWithNull(String name, TestData.OfRef<Integer> data) {
List<Integer> objects = exerciseTerminalOps(data, s -> s.toList());
checkUnmodifiable(objects);
assertTrue(objects.contains(null));
}
@Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
public void testDefaultOps(String name, TestData.OfRef<Integer> data) {
List<Integer> objects = exerciseTerminalOps(data, s -> DefaultMethodStreams.delegateTo(s).toList());
checkUnmodifiable(objects);
assertFalse(objects.contains(null));
}
@Test(dataProvider = "withNull:StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
public void testDefaultOpsWithNull(String name, TestData.OfRef<Integer> data) {
List<Integer> objects = exerciseTerminalOps(data, s -> DefaultMethodStreams.delegateTo(s).toList());
checkUnmodifiable(objects);
assertTrue(objects.contains(null));
}
}

View file

@ -0,0 +1,304 @@
/*
* Copyright (c) 2015, 2024, 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.
*/
package org.openjdk.tests.java.util.stream;
import org.testng.annotations.Test;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
import java.util.function.BooleanSupplier;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.DefaultMethodStreams;
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 static java.util.stream.Collectors.toCollection;
/*
* @test
* @bug 8071597
*/
@Test
public class WhileOpStatefulTest extends OpTestCase {
static final long COUNT_PERIOD = 100;
static final long EXECUTION_TIME_LIMIT = TimeUnit.SECONDS.toMillis(10);
static final long TAKE_WHILE_COUNT_LIMIT = 100_000;
static final int DROP_SOURCE_SIZE = 10_000;
static final long DROP_WHILE_COUNT_LIMIT = 5000;
@Test
public void testTimedTakeWithCount() {
testTakeWhileMulti(
s -> {
BooleanSupplier isWithinTakePeriod =
within(System.currentTimeMillis(), COUNT_PERIOD);
s.takeWhile(e -> isWithinTakePeriod.getAsBoolean())
.mapToLong(e -> 1).reduce(0, Long::sum);
},
s -> {
BooleanSupplier isWithinTakePeriod =
within(System.currentTimeMillis(), COUNT_PERIOD);
s.takeWhile(e -> isWithinTakePeriod.getAsBoolean())
.mapToLong(e -> 1).reduce(0, Long::sum);
},
s -> {
BooleanSupplier isWithinTakePeriod =
within(System.currentTimeMillis(), COUNT_PERIOD);
s.takeWhile(e -> isWithinTakePeriod.getAsBoolean())
.map(e -> 1).reduce(0, Long::sum);
},
s -> {
BooleanSupplier isWithinTakePeriod =
within(System.currentTimeMillis(), COUNT_PERIOD);
s.takeWhile(e -> isWithinTakePeriod.getAsBoolean())
.mapToLong(e -> 1).reduce(0, Long::sum);
});
}
@Test(groups = { "serialization-hostile" })
public void testCountTakeWithCount() {
testTakeWhileMulti(
s -> {
AtomicLong c = new AtomicLong();
long rc = s.takeWhile(e -> c.getAndIncrement() < TAKE_WHILE_COUNT_LIMIT)
.mapToLong(e -> 1).reduce(0, Long::sum);
assertTrue(rc <= c.get());
},
s -> {
AtomicLong c = new AtomicLong();
long rc = s.takeWhile(e -> c.getAndIncrement() < TAKE_WHILE_COUNT_LIMIT)
.mapToLong(e -> 1).reduce(0, Long::sum);
assertTrue(rc <= c.get());
},
s -> {
AtomicLong c = new AtomicLong();
long rc = s.takeWhile(e -> c.getAndIncrement() < TAKE_WHILE_COUNT_LIMIT)
.map(e -> 1).reduce(0, Long::sum);
assertTrue(rc <= c.get());
},
s -> {
AtomicLong c = new AtomicLong();
long rc = s.takeWhile(e -> c.getAndIncrement() < TAKE_WHILE_COUNT_LIMIT)
.mapToLong(e -> 1).reduce(0, Long::sum);
assertTrue(rc <= c.get());
});
}
@Test(groups = { "serialization-hostile" })
public void testCountTakeWithToArray() {
testTakeWhileMulti(
s -> {
AtomicLong c = new AtomicLong();
Object[] ra = s.takeWhile(e -> c.getAndIncrement() < TAKE_WHILE_COUNT_LIMIT)
.toArray();
assertTrue(ra.length <= c.get());
},
s -> {
AtomicLong c = new AtomicLong();
int[] ra = s.takeWhile(e -> c.getAndIncrement() < TAKE_WHILE_COUNT_LIMIT)
.toArray();
assertTrue(ra.length <= c.get());
},
s -> {
AtomicLong c = new AtomicLong();
long[] ra = s.takeWhile(e -> c.getAndIncrement() < TAKE_WHILE_COUNT_LIMIT)
.toArray();
assertTrue(ra.length <= c.get());
},
s -> {
AtomicLong c = new AtomicLong();
double[] ra = s.takeWhile(e -> c.getAndIncrement() < TAKE_WHILE_COUNT_LIMIT)
.toArray();
assertTrue(ra.length <= c.get());
});
}
@Test(groups = { "serialization-hostile" })
public void testCountDropWithCount() {
testDropWhileMulti(
s -> {
AtomicLong c = new AtomicLong();
long rc = s.dropWhile(e -> c.getAndIncrement() < DROP_WHILE_COUNT_LIMIT)
.mapToLong(e -> 1).reduce(0, Long::sum);
assertTrue(c.get() >= DROP_WHILE_COUNT_LIMIT);
assertTrue(rc <= DROP_SOURCE_SIZE);
},
s -> {
AtomicLong c = new AtomicLong();
long rc = s.dropWhile(e -> c.getAndIncrement() < DROP_WHILE_COUNT_LIMIT)
.mapToLong(e -> 1).reduce(0, Long::sum);
assertTrue(c.get() >= DROP_WHILE_COUNT_LIMIT);
assertTrue(rc <= DROP_SOURCE_SIZE);
},
s -> {
AtomicLong c = new AtomicLong();
long rc = s.dropWhile(e -> c.getAndIncrement() < DROP_WHILE_COUNT_LIMIT)
.map(e -> 1).reduce(0, Long::sum);
assertTrue(c.get() >= DROP_WHILE_COUNT_LIMIT);
assertTrue(rc <= DROP_SOURCE_SIZE);
},
s -> {
AtomicLong c = new AtomicLong();
long rc = s.dropWhile(e -> c.getAndIncrement() < DROP_WHILE_COUNT_LIMIT)
.mapToLong(e -> 1).reduce(0, Long::sum);
assertTrue(c.get() >= DROP_WHILE_COUNT_LIMIT);
assertTrue(rc <= DROP_SOURCE_SIZE);
});
}
@Test(groups = { "serialization-hostile" })
public void testCountDropWithToArray() {
testDropWhileMulti(
s -> {
AtomicLong c = new AtomicLong();
Object[] ra = s.dropWhile(e -> c.getAndIncrement() < DROP_WHILE_COUNT_LIMIT)
.toArray();
assertTrue(c.get() >= DROP_WHILE_COUNT_LIMIT);
assertTrue(ra.length <= DROP_SOURCE_SIZE);
},
s -> {
AtomicLong c = new AtomicLong();
int[] ra = s.dropWhile(e -> c.getAndIncrement() < DROP_WHILE_COUNT_LIMIT)
.toArray();
assertTrue(c.get() >= DROP_WHILE_COUNT_LIMIT);
assertTrue(ra.length <= DROP_SOURCE_SIZE);
},
s -> {
AtomicLong c = new AtomicLong();
long[] ra = s.dropWhile(e -> c.getAndIncrement() < DROP_WHILE_COUNT_LIMIT)
.toArray();
assertTrue(c.get() >= DROP_WHILE_COUNT_LIMIT);
assertTrue(ra.length <= DROP_SOURCE_SIZE);
},
s -> {
AtomicLong c = new AtomicLong();
double[] ra = s.dropWhile(e -> c.getAndIncrement() < DROP_WHILE_COUNT_LIMIT)
.toArray();
assertTrue(c.get() >= DROP_WHILE_COUNT_LIMIT);
assertTrue(ra.length <= DROP_SOURCE_SIZE);
});
}
private void testTakeWhileMulti(Consumer<Stream<Integer>> mRef,
Consumer<IntStream> mInt,
Consumer<LongStream> mLong,
Consumer<DoubleStream> mDouble) {
Map<String, Supplier<Stream<Integer>>> sources = new HashMap<>();
sources.put("Stream.generate()", () -> Stream.generate(() -> 1));
sources.put("Stream.iterate()", () -> Stream.iterate(1, x -> 1));
sources.put("Stream.iterate().unordered()", () -> Stream.iterate(1, x -> 1));
testWhileMulti(sources, mRef, mInt, mLong, mDouble);
}
private void testDropWhileMulti(Consumer<Stream<Integer>> mRef,
Consumer<IntStream> mInt,
Consumer<LongStream> mLong,
Consumer<DoubleStream> mDouble) {
Map<String, Supplier<Stream<Integer>>> sources = new HashMap<>();
sources.put("IntStream.range().boxed()",
() -> IntStream.range(0, DROP_SOURCE_SIZE).boxed());
sources.put("IntStream.range().boxed().unordered()",
() -> IntStream.range(0, DROP_SOURCE_SIZE).boxed().unordered());
sources.put("LinkedList.stream()",
() -> IntStream.range(0, DROP_SOURCE_SIZE).boxed()
.collect(toCollection(LinkedList::new))
.stream());
sources.put("LinkedList.stream().unordered()",
() -> IntStream.range(0, DROP_SOURCE_SIZE).boxed()
.collect(toCollection(LinkedList::new))
.stream()
.unordered());
testWhileMulti(sources, mRef, mInt, mLong, mDouble);
}
private void testWhileMulti(Map<String, Supplier<Stream<Integer>>> sources,
Consumer<Stream<Integer>> mRef,
Consumer<IntStream> mInt,
Consumer<LongStream> mLong,
Consumer<DoubleStream> mDouble) {
Map<String, Function<Stream<Integer>, Stream<Integer>>> transforms = new HashMap<>();
transforms.put("Stream.sequential()", s -> {
BooleanSupplier isWithinExecutionPeriod = within(System.currentTimeMillis(),
EXECUTION_TIME_LIMIT);
return s.peek(e -> {
if (!isWithinExecutionPeriod.getAsBoolean()) {
throw new RuntimeException("Execution time limit exceeded!");
}
});
});
transforms.put("Stream.parallel()", s -> {
BooleanSupplier isWithinExecutionPeriod = within(System.currentTimeMillis(),
EXECUTION_TIME_LIMIT);
return s.parallel()
.peek(e -> {
if (!isWithinExecutionPeriod.getAsBoolean()) {
throw new RuntimeException("Execution time limit exceeded!");
}
});
});
Map<String, Consumer<Stream<Integer>>> actions = new HashMap<>();
actions.put("Ref", mRef);
actions.put("Int", s -> mInt.accept(s.mapToInt(e -> e)));
actions.put("Long", s -> mLong.accept(s.mapToLong(e -> e)));
actions.put("Double", s -> mDouble.accept(s.mapToDouble(e -> e)));
actions.put("Ref using defaults", s -> mRef.accept(DefaultMethodStreams.delegateTo(s)));
actions.put("Int using defaults", s -> mInt.accept(DefaultMethodStreams.delegateTo(s.mapToInt(e -> e))));
actions.put("Long using defaults", s -> mLong.accept(DefaultMethodStreams.delegateTo(s.mapToLong(e -> e))));
actions.put("Double using defaults", s -> mDouble.accept(DefaultMethodStreams.delegateTo(s.mapToDouble(e -> e))));
for (Map.Entry<String, Supplier<Stream<Integer>>> s : sources.entrySet()) {
setContext("source", s.getKey());
for (Map.Entry<String, Function<Stream<Integer>, Stream<Integer>>> t : transforms.entrySet()) {
setContext("transform", t.getKey());
for (Map.Entry<String, Consumer<Stream<Integer>>> a : actions.entrySet()) {
setContext("shape", a.getKey());
Stream<Integer> stream = s.getValue().get();
stream = t.getValue().apply(stream);
a.getValue().accept(stream);
}
}
}
}
static BooleanSupplier within(long start, long durationInMillis) {
return () -> (System.currentTimeMillis() - start) < durationInMillis;
}
}

View file

@ -0,0 +1,393 @@
/*
* Copyright (c) 2015, 2025, 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.
*/
package org.openjdk.tests.java.util.stream;
import org.testng.annotations.Test;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.DefaultMethodStreams;
import java.util.stream.DoubleStream;
import java.util.stream.IntStream;
import java.util.stream.LambdaTestHelpers;
import java.util.stream.LongStream;
import java.util.stream.OpTestCase;
import java.util.stream.Stream;
import java.util.stream.StreamTestDataProvider;
import java.util.stream.TestData;
/*
* @test
* @bug 8071597 8193856
*/
@Test
public class WhileOpTest extends OpTestCase {
@Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class,
groups = { "serialization-hostile" })
public void testTakeWhileOps(String name, TestData.OfRef<Integer> data) {
for (int size : sizes(data.size())) {
setContext("takeWhile", size);
testWhileMulti(data,
whileResultAsserter(data, WhileOp.Take, e -> e < size),
s -> s.takeWhile(e -> e < size),
s -> s.takeWhile(e -> e < size),
s -> s.takeWhile(e -> e < size),
s -> s.takeWhile(e -> e < size));
testWhileMulti(data,
whileResultAsserter(data, WhileOp.Take, e -> e < size / 2),
s -> s.takeWhile(e -> e < size).takeWhile(e -> e < size / 2),
s -> s.takeWhile(e -> e < size).takeWhile(e -> e < size / 2),
s -> s.takeWhile(e -> e < size).takeWhile(e -> e < size / 2),
s -> s.takeWhile(e -> e < size).takeWhile(e -> e < size / 2));
}
}
@Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class,
groups = { "serialization-hostile" })
public void testDropWhileOps(String name, TestData.OfRef<Integer> data) {
for (int size : sizes(data.size())) {
setContext("dropWhile", size);
testWhileMulti(data,
whileResultAsserter(data, WhileOp.Drop, e -> e < size),
s -> s.dropWhile(e -> e < size),
s -> s.dropWhile(e -> e < size),
s -> s.dropWhile(e -> e < size),
s -> s.dropWhile(e -> e < size));
testWhileMulti(data,
whileResultAsserter(data, WhileOp.Drop, e -> e < size),
s -> s.dropWhile(e -> e < size / 2).dropWhile(e -> e < size),
s -> s.dropWhile(e -> e < size / 2).dropWhile(e -> e < size),
s -> s.dropWhile(e -> e < size / 2).dropWhile(e -> e < size),
s -> s.dropWhile(e -> e < size / 2).dropWhile(e -> e < size));
}
}
@Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class,
groups = { "serialization-hostile" })
public void testDropTakeWhileOps(String name, TestData.OfRef<Integer> data) {
for (int size : sizes(data.size())) {
setContext("dropWhile", size);
testWhileMulti(data,
whileResultAsserter(data, WhileOp.Undefined, null),
s -> s.dropWhile(e -> e < size / 2).takeWhile(e -> e < size),
s -> s.dropWhile(e -> e < size / 2).takeWhile(e -> e < size),
s -> s.dropWhile(e -> e < size / 2).takeWhile(e -> e < size),
s -> s.dropWhile(e -> e < size / 2).takeWhile(e -> e < size));
}
}
/**
* While operation type to be asserted on
*/
enum WhileOp {
/**
* The takeWhile operation
*/
Take,
/**
* The dropWhile operation
*/
Drop,
/**
* The operation(s) are undefined
*/
Undefined
}
/**
* Create a result asserter for takeWhile or dropWhile operations.
* <p>
* If the stream pipeline consists of the takeWhile operation
* ({@link WhileOp#Take}) or the dropWhile operation ({@link WhileOp#Drop})
* then specific assertions can be made on the actual result based on the
* input elements, {@code inputData}, and whether those elements match the
* predicate, {@code p}, of the operation.
* <p>
* If the input elements have an encounter order then the actual result
* is asserted against the result of operating sequentially on input
* elements given the predicate and in accordance with the operation
* semantics. (The actual result whether produced sequentially or in
* parallel should the same.)
* <p>
* If the input elements have no encounter order then an actual result
* is, for practical purposes, considered non-deterministic.
* Consider an input list of lists that contains all possible permutations
* of the input elements, and a output list of lists that is the result of
* applying the pipeline with the operation sequentially to each input
* list.
* Any list in the output lists is a valid result. It's not practical to
* test in such a manner.
* For a takeWhile operation the following assertions can be made if
* only some of the input elements match the predicate (i.e. taking will
* short-circuit the pipeline):
* <ol>
* <li>The set of output elements is a subset of the set of matching
* input elements</li>
* <li>The set of output elements and the set of non-matching input
* element are disjoint</li>
* </ol>
* For a dropWhile operation the following assertions can be made:
* <ol>
* <li>The set of non-matching input elements is a subset of the set of
* output elements</li>
* <li>The set of matching output elements is a subset of the set of
* matching input elements</li>
* </ol>
*
* @param inputData the elements input into the stream pipeline
* @param op the operation of the stream pipeline, one of takeWhile,
* dropWhile, or an undefined set of operations (possibly including
* two or more takeWhile and/or dropWhile operations, or because
* the predicate is not stateless).
* @param p the stateless predicate applied to the operation, ignored if
* the
* operation is {@link WhileOp#Undefined}.
* @param <T> the type of elements
* @return a result asserter
*/
private <T> ResultAsserter<Iterable<T>> whileResultAsserter(Iterable<T> inputData,
WhileOp op,
Predicate<? super T> p) {
return (act, exp, ord, par) -> {
if (par & !ord) {
List<T> input = new ArrayList<>();
inputData.forEach(input::add);
List<T> output = new ArrayList<>();
act.forEach(output::add);
if (op == WhileOp.Take) {
List<T> matchingInput = new ArrayList<>();
List<T> nonMatchingInput = new ArrayList<>();
input.forEach(t -> {
if (p.test(t))
matchingInput.add(t);
else
nonMatchingInput.add(t);
});
// If some, not all, elements are taken
if (matchingInput.size() < input.size()) {
assertTrue(output.size() <= matchingInput.size(),
"Output is larger than the matching input");
// The output must be a subset of the matching input
assertTrue(matchingInput.containsAll(output),
"Output is not a subset of the matching input");
// The output must not contain any non matching elements
for (T nonMatching : nonMatchingInput) {
assertFalse(output.contains(nonMatching),
"Output and non-matching input are not disjoint");
}
}
}
else if (op == WhileOp.Drop) {
List<T> matchingInput = new ArrayList<>();
List<T> nonMatchingInput = new ArrayList<>();
input.forEach(t -> {
if (p.test(t))
matchingInput.add(t);
else
nonMatchingInput.add(t);
});
// The non matching input must be a subset of output
assertTrue(output.containsAll(nonMatchingInput),
"Non-matching input is not a subset of the output");
// The matching output must be a subset of the matching input
List<T> matchingOutput = new ArrayList<>();
output.forEach(i -> {
if (p.test(i))
matchingOutput.add(i);
});
assertTrue(matchingInput.containsAll(matchingOutput),
"Matching output is not a subset of matching input");
}
// Note: if there is a combination of takeWhile and dropWhile then specific
// assertions cannot be performed.
// All that can be reliably asserted is the output is a subset of the input
assertTrue(input.containsAll(output));
}
else {
// For specific operations derive expected result from the input
if (op == WhileOp.Take) {
List<T> takeInput = new ArrayList<>();
for (T t : inputData) {
if (p.test(t))
takeInput.add(t);
else
break;
}
LambdaTestHelpers.assertContents(act, takeInput);
}
else if (op == WhileOp.Drop) {
List<T> dropInput = new ArrayList<>();
for (T t : inputData) {
if (dropInput.size() > 0 || !p.test(t))
dropInput.add(t);
}
LambdaTestHelpers.assertContents(act, dropInput);
}
LambdaTestHelpers.assertContents(act, exp);
}
};
}
private Collection<Integer> sizes(int s) {
Set<Integer> sizes = new LinkedHashSet<>();
sizes.add(0);
sizes.add(1);
sizes.add(s / 4);
sizes.add(s / 2);
sizes.add(3 * s / 4);
sizes.add(Math.max(0, s - 1));
sizes.add(s);
sizes.add(Integer.MAX_VALUE);
return sizes;
}
private void testWhileMulti(TestData.OfRef<Integer> data,
ResultAsserter<Iterable<Integer>> ra,
Function<Stream<Integer>, Stream<Integer>> mRef,
Function<IntStream, IntStream> mInt,
Function<LongStream, LongStream> mLong,
Function<DoubleStream, DoubleStream> mDouble) {
Map<String, Function<Stream<Integer>, Stream<Integer>>> ms = new HashMap<>();
ms.put("Ref", mRef);
ms.put("Int", s -> mInt.apply(s.mapToInt(e -> e)).mapToObj(e -> e));
ms.put("Long", s -> mLong.apply(s.mapToLong(e -> e)).mapToObj(e -> (int) e));
ms.put("Double", s -> mDouble.apply(s.mapToDouble(e -> e)).mapToObj(e -> (int) e));
ms.put("Ref using defaults", s -> mRef.apply(DefaultMethodStreams.delegateTo(s)));
ms.put("Int using defaults", s -> mInt.apply(DefaultMethodStreams.delegateTo(s.mapToInt(e -> e))).mapToObj(e -> e));
ms.put("Long using defaults", s -> mLong.apply(DefaultMethodStreams.delegateTo(s.mapToLong(e -> e))).mapToObj(e -> (int) e));
ms.put("Double using defaults", s -> mDouble.apply(DefaultMethodStreams.delegateTo(s.mapToDouble(e -> e))).mapToObj(e -> (int) e));
testWhileMulti(data, ra, ms);
}
private final void testWhileMulti(TestData.OfRef<Integer> data,
ResultAsserter<Iterable<Integer>> ra,
Map<String, Function<Stream<Integer>, Stream<Integer>>> ms) {
for (Map.Entry<String, Function<Stream<Integer>, Stream<Integer>>> e : ms.entrySet()) {
setContext("shape", e.getKey());
withData(data)
.stream(e.getValue())
.resultAsserter(ra)
.exercise();
}
}
@Test(groups = { "serialization-hostile" })
public void testRefDefaultClose() {
AtomicBoolean isClosed = new AtomicBoolean();
Stream<Integer> s = Stream.of(1, 2, 3).onClose(() -> isClosed.set(true));
try (Stream<Integer> ds = DefaultMethodStreams.delegateTo(s).takeWhile(e -> e < 3)) {
ds.count();
}
assertTrue(isClosed.get());
}
@Test(groups = { "serialization-hostile" })
public void testIntDefaultClose() {
AtomicBoolean isClosed = new AtomicBoolean();
IntStream s = IntStream.of(1, 2, 3).onClose(() -> isClosed.set(true));
try (IntStream ds = DefaultMethodStreams.delegateTo(s).takeWhile(e -> e < 3)) {
ds.count();
}
assertTrue(isClosed.get());
}
@Test(groups = { "serialization-hostile" })
public void testLongDefaultClose() {
AtomicBoolean isClosed = new AtomicBoolean();
LongStream s = LongStream.of(1, 2, 3).onClose(() -> isClosed.set(true));
try (LongStream ds = DefaultMethodStreams.delegateTo(s).takeWhile(e -> e < 3)) {
ds.count();
}
assertTrue(isClosed.get());
}
@Test(groups = { "serialization-hostile" })
public void testDoubleDefaultClose() {
AtomicBoolean isClosed = new AtomicBoolean();
DoubleStream s = DoubleStream.of(1, 2, 3).onClose(() -> isClosed.set(true));
try (DoubleStream ds = DefaultMethodStreams.delegateTo(s).takeWhile(e -> e < 3)) {
ds.count();
}
assertTrue(isClosed.get());
}
@Test(groups = { "serialization-hostile" })
public void testFlatMapThenTake() {
TestData.OfRef<Integer> range = TestData.Factory.ofSupplier(
"range", () -> IntStream.range(0, 100).boxed());
exerciseOpsMulti(range,
// Reference result
s -> s.takeWhile(e -> e != 50),
// For other results collect into array,
// stream the single array (not the elements),
// then flat map to stream the array elements
s -> Stream.<Integer[]>of(s.toArray(Integer[]::new)).
flatMap(Stream::of).
takeWhile(e -> e != 50),
s -> Stream.of(s.mapToInt(e -> e).toArray()).
flatMapToInt(IntStream::of).
takeWhile(e -> e != 50).
mapToObj(e -> e),
s -> Stream.of(s.mapToLong(e -> e).toArray()).
flatMapToLong(LongStream::of).
takeWhile(e -> e != 50L).
mapToObj(e -> (int) e),
s -> Stream.of(s.mapToDouble(e -> e).toArray()).
flatMapToDouble(DoubleStream::of).
takeWhile(e -> e != 50.0).
mapToObj(e -> (int) e)
);
}
}

View file

@ -0,0 +1,323 @@
/*
* Copyright (c) 2020, 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
* @summary Test mapMulti(BiConsumer) and primitive stream operations
*/
package org.openjdk.tests.java.util.stream;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import java.util.Arrays;
import java.util.Collection;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.DefaultMethodStreams;
import java.util.stream.DoubleStream;
import java.util.stream.DoubleStreamTestDataProvider;
import java.util.stream.IntStream;
import java.util.stream.IntStreamTestDataProvider;
import java.util.stream.LongStream;
import java.util.stream.LongStreamTestDataProvider;
import java.util.stream.OpTestCase;
import java.util.stream.Stream;
import java.util.stream.StreamTestDataProvider;
import java.util.stream.TestData;
import static java.util.stream.DefaultMethodStreams.delegateTo;
import static java.util.stream.LambdaTestHelpers.LONG_STRING;
import static java.util.stream.LambdaTestHelpers.assertConcat;
import static java.util.stream.LambdaTestHelpers.assertContents;
import static java.util.stream.LambdaTestHelpers.assertCountSum;
import static java.util.stream.LambdaTestHelpers.countTo;
import static java.util.stream.LambdaTestHelpers.flattenChars;
import static java.util.stream.LambdaTestHelpers.mfId;
import static java.util.stream.LambdaTestHelpers.mfLt;
import static java.util.stream.LambdaTestHelpers.mfNull;
import static java.util.stream.ThrowableHelper.checkNPE;
@Test
public class mapMultiOpTest extends OpTestCase {
BiConsumer<Integer, Consumer<Integer>> nullConsumer =
(e, sink) -> mfNull.apply(e).forEach(sink);
BiConsumer<Integer, Consumer<Integer>> idConsumer =
(e, sink) -> mfId.apply(e).forEach(sink);
BiConsumer<Integer, Consumer<Integer>> listConsumer =
(e, sink) -> mfLt.apply(e).forEach(sink);
BiConsumer<String, Consumer<Character>> charConsumer =
(e, sink) -> flattenChars.apply(e).forEach(sink);
BiConsumer<Integer, Consumer<Integer>> emptyStreamConsumer =
(e, sink) -> Stream.empty().forEach(i -> sink.accept((Integer) i));
BiConsumer<Integer, Consumer<Integer>> intRangeConsumer =
(e, sink) -> IntStream.range(0, e).boxed().forEach(sink);
BiConsumer<Integer, Consumer<Integer>> rangeConsumerWithLimit =
(e, sink) -> IntStream.range(0, e).boxed().limit(10).forEach(sink);
@DataProvider(name = "Stream<Integer>")
public Object[][] streamProvider() {
return new Object[][]{
{Stream.of(0, 1, 2)},
{DefaultMethodStreams.delegateTo(Stream.of(0, 1, 2))}
};
}
@Test(dataProvider = "Stream<Integer>")
public void testNullMapper(Stream<Integer> s) {
checkNPE(() -> s.mapMulti(null));
checkNPE(() -> s.mapMultiToInt(null));
checkNPE(() -> s.mapMultiToDouble(null));
checkNPE(() -> s.mapMultiToLong(null));
}
@Test
public void testMapMulti() {
String[] stringsArray = {"hello", "there", "", "yada"};
Stream<String> strings = Arrays.asList(stringsArray).stream();
assertConcat(strings.mapMulti(charConsumer)
.iterator(), "hellothereyada");
assertCountSum((countTo(10).stream().mapMulti(idConsumer)),
10, 55);
assertCountSum(countTo(10).stream().mapMulti(nullConsumer),
0, 0);
assertCountSum(countTo(3).stream().mapMulti(listConsumer),
6, 4);
exerciseOps(TestData.Factory.ofArray("stringsArray",
stringsArray), s -> s.mapMulti(charConsumer));
exerciseOps(TestData.Factory.ofArray("LONG_STRING",
new String[]{LONG_STRING}), s -> s.mapMulti(charConsumer));
}
@Test
public void testDefaultMapMulti() {
String[] stringsArray = {"hello", "there", "", "yada"};
Stream<String> strings = Arrays.stream(stringsArray);
assertConcat(delegateTo(strings)
.mapMulti(charConsumer).iterator(), "hellothereyada");
assertCountSum(delegateTo(countTo(10).stream())
.mapMulti(idConsumer), 10, 55);
assertCountSum(delegateTo(countTo(10).stream())
.mapMulti(nullConsumer), 0, 0);
assertCountSum(delegateTo(countTo(3).stream())
.mapMulti(listConsumer), 6, 4);
exerciseOps(TestData.Factory.ofArray("stringsArray",
stringsArray), s -> delegateTo(s).mapMulti(charConsumer));
exerciseOps(TestData.Factory.ofArray("LONG_STRING",
new String[]{LONG_STRING}), s -> delegateTo(s).mapMulti(charConsumer));
}
@Test(dataProvider = "StreamTestData<Integer>",
dataProviderClass = StreamTestDataProvider.class)
public void testOps(String name, TestData.OfRef<Integer> data) {
testOps(name, data, s -> s);
testOps(name, data, s -> delegateTo(s));
}
private void testOps(String name,
TestData.OfRef<Integer> data,
Function<Stream<Integer>, Stream<Integer>> sf) {
Collection<Integer> result;
result = exerciseOps(data, s -> sf.apply(s).mapMulti(idConsumer));
assertEquals(data.size(), result.size());
result = exerciseOps(data, s -> sf.apply(s).mapMulti(nullConsumer));
assertEquals(0, result.size());
result = exerciseOps(data, s -> sf.apply(s).mapMulti(emptyStreamConsumer));
assertEquals(0, result.size());
}
@Test(dataProvider = "StreamTestData<Integer>.small",
dataProviderClass = StreamTestDataProvider.class)
public void testOpsX(String name, TestData.OfRef<Integer> data) {
exerciseOps(data, s -> s.mapMulti(listConsumer));
exerciseOps(data, s -> s.mapMulti(intRangeConsumer));
exerciseOps(data, s -> s.mapMulti(rangeConsumerWithLimit));
}
@Test(dataProvider = "StreamTestData<Integer>.small",
dataProviderClass = StreamTestDataProvider.class)
public void testDefaultOpsX(String name, TestData.OfRef<Integer> data) {
exerciseOps(data, s -> delegateTo(s).mapMulti(listConsumer));
exerciseOps(data, s -> delegateTo(s).mapMulti(intRangeConsumer));
exerciseOps(data, s -> delegateTo(s).mapMulti(rangeConsumerWithLimit));
}
// Int
@DataProvider(name = "IntStream")
public Object[][] intStreamProvider() {
return new Object[][]{
{IntStream.of(0, 1, 2)},
{DefaultMethodStreams.delegateTo(IntStream.of(0, 1, 2))}
};
}
@Test(dataProvider = "IntStream")
public void testIntNullMapper(IntStream s) {
checkNPE(() -> s.mapMulti(null));
}
@Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
public void testIntOps(String name, TestData.OfInt data) {
testIntOps(name, data, s -> s);
testIntOps(name, data, s -> delegateTo(s));
}
private void testIntOps(String name,
TestData.OfInt data,
Function<IntStream, IntStream> sf) {
Collection<Integer> result = exerciseOps(data, s -> sf.apply(s).mapMulti((i, sink) -> IntStream.of(i).forEach(sink)));
assertEquals(data.size(), result.size());
assertContents(data, result);
result = exerciseOps(data, s -> sf.apply(s).boxed().mapMultiToInt((i, sink) -> IntStream.of(i).forEach(sink)));
assertEquals(data.size(), result.size());
assertContents(data, result);
result = exerciseOps(data, s -> sf.apply(s).mapMulti((i, sink) -> IntStream.empty().forEach(sink)));
assertEquals(0, result.size());
}
@Test(dataProvider = "IntStreamTestData.small", dataProviderClass = IntStreamTestDataProvider.class)
public void testIntOpsX(String name, TestData.OfInt data) {
exerciseOps(data, s -> s.mapMulti((e, sink) -> IntStream.range(0, e).forEach(sink)));
exerciseOps(data, s -> s.mapMulti((e, sink) -> IntStream.range(0, e).limit(10).forEach(sink)));
exerciseOps(data, s -> s.boxed().mapMultiToInt((e, sink) -> IntStream.range(0, e).forEach(sink)));
exerciseOps(data, s -> s.boxed().mapMultiToInt((e, sink) -> IntStream.range(0, e).limit(10).forEach(sink)));
}
@Test(dataProvider = "IntStreamTestData.small", dataProviderClass = IntStreamTestDataProvider.class)
public void testDefaultIntOpsX(String name, TestData.OfInt data) {
exerciseOps(data, s -> delegateTo(s).mapMulti((e, sink) -> IntStream.range(0, e).forEach(sink)));
exerciseOps(data, s -> delegateTo(s).mapMulti((e, sink) -> IntStream.range(0, e).limit(10).forEach(sink)));
exerciseOps(data, s -> delegateTo(s).boxed().mapMultiToInt((e, sink) -> IntStream.range(0, e).forEach(sink)));
exerciseOps(data, s -> delegateTo(s).boxed().mapMultiToInt((e, sink) -> IntStream.range(0, e).limit(10).forEach(sink)));
}
// Double
@DataProvider(name = "DoubleStream")
public Object[][] doubleStreamProvider() {
return new Object[][]{
{DoubleStream.of(0, 1, 2)},
{DefaultMethodStreams.delegateTo(DoubleStream.of(0, 1, 2))}
};
}
@Test(dataProvider = "DoubleStream")
public void testDoubleNullMapper(DoubleStream s) {
checkNPE(() -> s.mapMulti(null));
}
@Test(dataProvider = "DoubleStreamTestData", dataProviderClass = DoubleStreamTestDataProvider.class)
public void testDoubleOps(String name, TestData.OfDouble data) {
testDoubleOps(name, data, s -> s);
testDoubleOps(name, data, s -> delegateTo(s));
}
private void testDoubleOps(String name,
TestData.OfDouble data,
Function<DoubleStream, DoubleStream> sf) {
Collection<Double> result = exerciseOps(data, s -> sf.apply(s).mapMulti((i, sink) -> DoubleStream.of(i).forEach(sink)));
assertEquals(data.size(), result.size());
assertContents(data, result);
result = exerciseOps(data, s -> sf.apply(s).boxed().mapMultiToDouble((i, sink) -> DoubleStream.of(i).forEach(sink)));
assertEquals(data.size(), result.size());
assertContents(data, result);
result = exerciseOps(data, s -> sf.apply(s).mapMulti((i, sink) -> DoubleStream.empty().forEach(sink)));
assertEquals(0, result.size());
}
@Test(dataProvider = "DoubleStreamTestData.small", dataProviderClass = DoubleStreamTestDataProvider.class)
public void testDoubleOpsX(String name, TestData.OfDouble data) {
exerciseOps(data, s -> s.mapMulti((e, sink) -> IntStream.range(0, (int) e).asDoubleStream().forEach(sink)));
exerciseOps(data, s -> s.mapMulti((e, sink) -> IntStream.range(0, (int) e).limit(10).asDoubleStream().forEach(sink)));
}
@Test(dataProvider = "DoubleStreamTestData.small", dataProviderClass = DoubleStreamTestDataProvider.class)
public void testDefaultDoubleOpsX(String name, TestData.OfDouble data) {
exerciseOps(data, s -> delegateTo(s).mapMulti((e, sink) -> IntStream.range(0, (int) e).asDoubleStream().forEach(sink)));
exerciseOps(data, s -> delegateTo(s).mapMulti((e, sink) -> IntStream.range(0, (int) e).limit(10).asDoubleStream().forEach(sink)));
}
// Long
@DataProvider(name = "LongStream")
public Object[][] longStreamProvider() {
return new Object[][]{
{LongStream.of(0, 1, 2)},
{DefaultMethodStreams.delegateTo(LongStream.of(0, 1, 2))}
};
}
@Test(dataProvider = "LongStream")
public void testLongNullMapper(LongStream s) {
checkNPE(() -> s.mapMulti(null));
}
@Test(dataProvider = "LongStreamTestData", dataProviderClass = LongStreamTestDataProvider.class)
public void testLongOps(String name, TestData.OfLong data) {
testLongOps(name, data, s -> s);
testLongOps(name, data, s -> delegateTo(s));
}
private void testLongOps(String name,
TestData.OfLong data,
Function<LongStream, LongStream> sf) {
Collection<Long> result = exerciseOps(data, s -> sf.apply(s).mapMulti((i, sink) -> LongStream.of(i).forEach(sink)));
assertEquals(data.size(), result.size());
assertContents(data, result);
result = exerciseOps(data, s -> sf.apply(s).boxed().mapMultiToLong((i, sink) -> LongStream.of(i).forEach(sink)));
assertEquals(data.size(), result.size());
assertContents(data, result);
result = exerciseOps(data, s -> sf.apply(s).mapMulti((i, sink) -> LongStream.empty().forEach(sink)));
assertEquals(0, result.size());
}
@Test(dataProvider = "LongStreamTestData.small", dataProviderClass = LongStreamTestDataProvider.class)
public void testLongOpsX(String name, TestData.OfLong data) {
exerciseOps(data, s -> s.mapMulti((e, sink) -> LongStream.range(0, e).forEach(sink)));
exerciseOps(data, s -> s.mapMulti((e, sink) -> LongStream.range(0, e).limit(10).forEach(sink)));
}
@Test(dataProvider = "LongStreamTestData.small", dataProviderClass = LongStreamTestDataProvider.class)
public void testDefaultLongOpsX(String name, TestData.OfLong data) {
exerciseOps(data, s -> delegateTo(s).mapMulti((e, sink) -> LongStream.range(0, e).forEach(sink)));
exerciseOps(data, s -> delegateTo(s).mapMulti((e, sink) -> LongStream.range(0, e).limit(10).forEach(sink)));
}
}