/* * 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.StreamTestDataProvider; import org.testng.annotations.Test; import org.testng.annotations.DataProvider; import org.testng.annotations.Factory; import java.util.*; 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.*; @Test public class ConcatOpTest extends OpTestCase { private static Object[][] cases; static { List part1 = Arrays.asList(5, 3, 4, 1, 2, 6, 2, 4); List part2 = Arrays.asList(8, 8, 6, 6, 9, 7, 10, 9); List p1p2 = Arrays.asList(5, 3, 4, 1, 2, 6, 2, 4, 8, 8, 6, 6, 9, 7, 10, 9); List p2p1 = Arrays.asList(8, 8, 6, 6, 9, 7, 10, 9, 5, 3, 4, 1, 2, 6, 2, 4); List empty = Collections.emptyList(); LinkedHashSet distinctP1 = new LinkedHashSet<>(part1); LinkedHashSet distinctP2 = new LinkedHashSet<>(part2); TreeSet sortedP1 = new TreeSet<>(part1); TreeSet 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) } }; } @DataProvider(name = "cases") private static Object[][] getCases() { return cases; } @Test public class ConcatTest { protected final String scenario; protected final Collection c1; protected final Collection c2; protected final Collection expected; ConcatTest(String scenario, Collection c1, Collection c2, Collection expected) { this.scenario = scenario; this.c1 = c1; this.c2 = c2; this.expected = expected; } private void assertConcat(Stream s1, Stream s2, boolean parallel, boolean ordered) { Stream result = Stream.concat(s1, s2); assertEquals(result.isParallel(), parallel); Spliterator sp = result.spliterator(); // 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 bothe are ordered assertEquals(sp.hasCharacteristics(Spliterator.ORDERED), ordered, scenario); // Verify elements assertEquals(toBoxedList(sp), expected, scenario); } public void testRefConcat() { // verify prerequisite Stream s1s = c1.stream(); Stream s2s = c2.stream(); Stream s1p = c1.parallelStream(); Stream 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)); // sequential + sequential -> sequential assertConcat(c1.stream(), c2.stream(), false, true); // parallel + parallel -> parallel assertConcat(c1.parallelStream(), c2.parallelStream(), true, true); // sequential + parallel -> parallel assertConcat(c1.stream(), c2.parallelStream(), true, true); // parallel + sequential -> parallel assertConcat(c1.parallelStream(), c2.stream(), true, true); // not ordered assertConcat(c1.stream().unordered(), c2.stream(), false, false); assertConcat(c1.stream(), c2.stream().unordered(), false, false); assertConcat(c1.parallelStream().unordered(), c2.stream().unordered(), true, false); } private void assertConcat(IntStream s1, IntStream s2, boolean parallel, boolean ordered) { IntStream result = IntStream.concat(s1, s2); assertEquals(result.isParallel(), parallel); Spliterator.OfInt sp = result.spliterator(); // 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 bothe are ordered assertEquals(sp.hasCharacteristics(Spliterator.ORDERED), ordered, scenario); // Verify elements assertEquals(toBoxedList(sp), expected, scenario); } public void testIntConcat() { // verify prerequisite IntStream s1s = c1.stream().mapToInt(Integer::intValue); IntStream s2s = c2.stream().mapToInt(Integer::intValue); IntStream s1p = c1.parallelStream().mapToInt(Integer::intValue); IntStream s2p = c2.parallelStream().mapToInt(Integer::intValue); 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)); // sequential + sequential -> sequential assertConcat(c1.stream().mapToInt(Integer::intValue), c2.stream().mapToInt(Integer::intValue), false, true); // parallel + parallel -> parallel assertConcat(c1.parallelStream().mapToInt(Integer::intValue), c2.parallelStream().mapToInt(Integer::intValue), true, true); // sequential + parallel -> parallel assertConcat(c1.stream().mapToInt(Integer::intValue), c2.parallelStream().mapToInt(Integer::intValue), true, true); // parallel + sequential -> parallel assertConcat(c1.parallelStream().mapToInt(Integer::intValue), c2.stream().mapToInt(Integer::intValue), true, true); // not ordered assertConcat(c1.stream().mapToInt(Integer::intValue).unordered(), c2.stream().mapToInt(Integer::intValue), false, false); assertConcat(c1.stream().mapToInt(Integer::intValue), c2.stream().mapToInt(Integer::intValue).unordered(), false, false); assertConcat(c1.parallelStream().mapToInt(Integer::intValue).unordered(), c2.stream().mapToInt(Integer::intValue).unordered(), true, false); } private void assertConcat(LongStream s1, LongStream s2, boolean parallel, boolean ordered) { LongStream result = LongStream.concat(s1, s2); assertEquals(result.isParallel(), parallel); Spliterator.OfLong sp = result.spliterator(); // 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 bothe are ordered assertEquals(sp.hasCharacteristics(Spliterator.ORDERED), ordered, scenario); // Verify elements assertEquals(toBoxedList(sp), toBoxedList(expected.stream().mapToLong(Integer::longValue).spliterator()), scenario); } public void testLongConcat() { // verify prerequisite LongStream s1s = c1.stream().mapToLong(Integer::longValue); LongStream s2s = c2.stream().mapToLong(Integer::longValue); LongStream s1p = c1.parallelStream().mapToLong(Integer::longValue); LongStream s2p = c2.parallelStream().mapToLong(Integer::longValue); 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)); // sequential + sequential -> sequential assertConcat(c1.stream().mapToLong(Integer::longValue), c2.stream().mapToLong(Integer::longValue), false, true); // parallel + parallel -> parallel assertConcat(c1.parallelStream().mapToLong(Integer::longValue), c2.parallelStream().mapToLong(Integer::longValue), true, true); // sequential + parallel -> parallel assertConcat(c1.stream().mapToLong(Integer::longValue), c2.parallelStream().mapToLong(Integer::longValue), true, true); // parallel + sequential -> parallel assertConcat(c1.parallelStream().mapToLong(Integer::longValue), c2.stream().mapToLong(Integer::longValue), true, true); // not ordered assertConcat(c1.stream().mapToLong(Integer::longValue).unordered(), c2.stream().mapToLong(Integer::longValue), false, false); assertConcat(c1.stream().mapToLong(Integer::longValue), c2.stream().mapToLong(Integer::longValue).unordered(), false, false); assertConcat(c1.parallelStream().mapToLong(Integer::longValue).unordered(), c2.stream().mapToLong(Integer::longValue).unordered(), true, false); } private void assertConcat(DoubleStream s1, DoubleStream s2, boolean parallel, boolean ordered) { DoubleStream result = DoubleStream.concat(s1, s2); assertEquals(result.isParallel(), parallel); Spliterator.OfDouble sp = result.spliterator(); // 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 bothe are ordered assertEquals(sp.hasCharacteristics(Spliterator.ORDERED), ordered, scenario); // Verify elements assertEquals(toBoxedList(sp), toBoxedList(expected.stream().mapToDouble(Integer::doubleValue).spliterator()), scenario); } public void testDoubleConcat() { // verify prerequisite DoubleStream s1s = c1.stream().mapToDouble(Integer::doubleValue); DoubleStream s2s = c2.stream().mapToDouble(Integer::doubleValue); DoubleStream s1p = c1.parallelStream().mapToDouble(Integer::doubleValue); DoubleStream s2p = c2.parallelStream().mapToDouble(Integer::doubleValue); 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)); // sequential + sequential -> sequential assertConcat(c1.stream().mapToDouble(Integer::doubleValue), c2.stream().mapToDouble(Integer::doubleValue), false, true); // parallel + parallel -> parallel assertConcat(c1.parallelStream().mapToDouble(Integer::doubleValue), c2.parallelStream().mapToDouble(Integer::doubleValue), true, true); // sequential + parallel -> parallel assertConcat(c1.stream().mapToDouble(Integer::doubleValue), c2.parallelStream().mapToDouble(Integer::doubleValue), true, true); // parallel + sequential -> parallel assertConcat(c1.parallelStream().mapToDouble(Integer::doubleValue), c2.stream().mapToDouble(Integer::doubleValue), true, true); // not ordered assertConcat(c1.stream().mapToDouble(Integer::doubleValue).unordered(), c2.stream().mapToDouble(Integer::doubleValue), false, false); assertConcat(c1.stream().mapToDouble(Integer::doubleValue), c2.stream().mapToDouble(Integer::doubleValue).unordered(), false, false); assertConcat(c1.parallelStream().mapToDouble(Integer::doubleValue).unordered(), c2.stream().mapToDouble(Integer::doubleValue).unordered(), true, false); } } @Factory(dataProvider = "cases") public Object[] createTests(String scenario, Collection c1, Collection c2, Collection expected) { return new Object[] { new ConcatTest(scenario, c1, c2, expected) }; } // Sanity to make sure all type of stream source works @Test(dataProvider = "StreamTestData", dataProviderClass = StreamTestDataProvider.class) public void testOpsSequential(String name, TestData.OfRef 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))); } }