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:
commit
0a580b313d
70422 changed files with 17213626 additions and 0 deletions
152
test/jdk/java/util/stream/CustomFJPoolTest.java
Normal file
152
test/jdk/java/util/stream/CustomFJPoolTest.java
Normal 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));
|
||||
}
|
||||
}
|
||||
229
test/jdk/java/util/stream/GathererAPITest.java
Normal file
229
test/jdk/java/util/stream/GathererAPITest.java
Normal 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());
|
||||
}
|
||||
}
|
||||
64
test/jdk/java/util/stream/GathererShortCircuitTest.java
Normal file
64
test/jdk/java/util/stream/GathererShortCircuitTest.java
Normal 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);
|
||||
}
|
||||
}
|
||||
514
test/jdk/java/util/stream/GathererTest.java
Normal file
514
test/jdk/java/util/stream/GathererTest.java
Normal 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!");
|
||||
}
|
||||
}
|
||||
91
test/jdk/java/util/stream/GatherersFoldTest.java
Normal file
91
test/jdk/java/util/stream/GatherersFoldTest.java
Normal 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);
|
||||
}
|
||||
}
|
||||
375
test/jdk/java/util/stream/GatherersMapConcurrentTest.java
Normal file
375
test/jdk/java/util/stream/GatherersMapConcurrentTest.java
Normal 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);
|
||||
}
|
||||
}
|
||||
102
test/jdk/java/util/stream/GatherersScanTest.java
Normal file
102
test/jdk/java/util/stream/GatherersScanTest.java
Normal 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);
|
||||
}
|
||||
}
|
||||
133
test/jdk/java/util/stream/GatherersWindowFixedTest.java
Normal file
133
test/jdk/java/util/stream/GatherersWindowFixedTest.java
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
138
test/jdk/java/util/stream/GatherersWindowSlidingTest.java
Normal file
138
test/jdk/java/util/stream/GatherersWindowSlidingTest.java
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
1
test/jdk/java/util/stream/TEST.properties
Normal file
1
test/jdk/java/util/stream/TEST.properties
Normal file
|
|
@ -0,0 +1 @@
|
|||
maxOutputSize=2000000
|
||||
169
test/jdk/java/util/stream/TestDoubleSumAverage.java
Normal file
169
test/jdk/java/util/stream/TestDoubleSumAverage.java
Normal 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;
|
||||
}
|
||||
}
|
||||
4
test/jdk/java/util/stream/boottest/TEST.properties
Normal file
4
test/jdk/java/util/stream/boottest/TEST.properties
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
# This file identifies root(s) of the test-ng hierarchy.
|
||||
|
||||
TestNG.dirs = .
|
||||
lib.dirs = /lib/testlibrary/bootlib
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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()));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
timeout.default.seconds=480
|
||||
72
test/jdk/java/util/stream/examples/JavadocExamples.java
Normal file
72
test/jdk/java/util/stream/examples/JavadocExamples.java
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
8
test/jdk/java/util/stream/test/TEST.properties
Normal file
8
test/jdk/java/util/stream/test/TEST.properties
Normal 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
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
|
@ -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)));
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
|
@ -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());
|
||||
}
|
||||
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
|
@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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)");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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")));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
timeout.default.seconds=480
|
||||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -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)));
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue