1 /* 2 * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 package org.openjdk.tests.java.util.stream; 24 25 import org.testng.annotations.DataProvider; 26 import org.testng.annotations.Factory; 27 import org.testng.annotations.Test; 28 29 import java.util.Arrays; 30 import java.util.Collection; 31 import java.util.Collections; 32 import java.util.LinkedHashSet; 33 import java.util.LinkedList; 34 import java.util.List; 35 import java.util.Spliterator; 36 import java.util.TreeSet; 37 import java.util.stream.DoubleStream; 38 import java.util.stream.IntStream; 39 import java.util.stream.LongStream; 40 import java.util.stream.Stream; 41 42 import static java.util.stream.LambdaTestHelpers.*; 43 import static org.testng.Assert.*; 44 45 @Test 46 public class ConcatTest { 47 private static Object[][] cases; 48 49 static { 50 List<Integer> part1 = Arrays.asList(5, 3, 4, 1, 2, 6, 2, 4); 51 List<Integer> part2 = Arrays.asList(8, 8, 6, 6, 9, 7, 10, 9); 52 List<Integer> p1p2 = Arrays.asList(5, 3, 4, 1, 2, 6, 2, 4, 8, 8, 6, 6, 9, 7, 10, 9); 53 List<Integer> p2p1 = Arrays.asList(8, 8, 6, 6, 9, 7, 10, 9, 5, 3, 4, 1, 2, 6, 2, 4); 54 List<Integer> empty = new LinkedList<>(); // To be ordered empty.isEmpty()55 assertTrue(empty.isEmpty()); 56 LinkedHashSet<Integer> distinctP1 = new LinkedHashSet<>(part1); 57 LinkedHashSet<Integer> distinctP2 = new LinkedHashSet<>(part2); 58 TreeSet<Integer> sortedP1 = new TreeSet<>(part1); 59 TreeSet<Integer> sortedP2 = new TreeSet<>(part2); 60 61 cases = new Object[][] { 62 { "regular", part1, part2, p1p2 }, 63 { "reverse regular", part2, part1, p2p1 }, 64 { "front distinct", distinctP1, part2, Arrays.asList(5, 3, 4, 1, 2, 6, 8, 8, 6, 6, 9, 7, 10, 9) }, 65 { "back distinct", part1, distinctP2, Arrays.asList(5, 3, 4, 1, 2, 6, 2, 4, 8, 6, 9, 7, 10) }, 66 { "both distinct", distinctP1, distinctP2, Arrays.asList(5, 3, 4, 1, 2, 6, 8, 6, 9, 7, 10) }, 67 { "front sorted", sortedP1, part2, Arrays.asList(1, 2, 3, 4, 5, 6, 8, 8, 6, 6, 9, 7, 10, 9) }, 68 { "back sorted", part1, sortedP2, Arrays.asList(5, 3, 4, 1, 2, 6, 2, 4, 6, 7, 8, 9, 10) }, 69 { "both sorted", sortedP1, sortedP2, Arrays.asList(1, 2, 3, 4, 5, 6, 6, 7, 8, 9, 10) }, 70 { "reverse both sorted", sortedP2, sortedP1, Arrays.asList(6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6) }, 71 { "empty something", empty, part1, part1 }, 72 { "something empty", part1, empty, part1 }, 73 { "empty empty", empty, empty, empty } 74 }; 75 } 76 77 @DataProvider(name = "cases") getCases()78 private static Object[][] getCases() { 79 return cases; 80 } 81 82 @Factory(dataProvider = "cases") createTests(String scenario, Collection<Integer> c1, Collection<Integer> c2, Collection<Integer> expected)83 public static Object[] createTests(String scenario, Collection<Integer> c1, Collection<Integer> c2, Collection<Integer> expected) { 84 return new Object[] { 85 new ConcatTest(scenario, c1, c2, expected) 86 }; 87 } 88 89 protected final String scenario; 90 protected final Collection<Integer> c1; 91 protected final Collection<Integer> c2; 92 protected final Collection<Integer> expected; 93 ConcatTest(String scenario, Collection<Integer> c1, Collection<Integer> c2, Collection<Integer> expected)94 public ConcatTest(String scenario, Collection<Integer> c1, Collection<Integer> c2, Collection<Integer> expected) { 95 this.scenario = scenario; 96 this.c1 = c1; 97 this.c2 = c2; 98 this.expected = expected; 99 100 // verify prerequisite 101 Stream<Integer> s1s = c1.stream(); 102 Stream<Integer> s2s = c2.stream(); 103 Stream<Integer> s1p = c1.parallelStream(); 104 Stream<Integer> s2p = c2.parallelStream(); 105 assertTrue(s1p.isParallel()); 106 assertTrue(s2p.isParallel()); 107 assertFalse(s1s.isParallel()); 108 assertFalse(s2s.isParallel()); 109 110 assertTrue(s1s.spliterator().hasCharacteristics(Spliterator.ORDERED)); 111 assertTrue(s1p.spliterator().hasCharacteristics(Spliterator.ORDERED)); 112 assertTrue(s2s.spliterator().hasCharacteristics(Spliterator.ORDERED)); 113 assertTrue(s2p.spliterator().hasCharacteristics(Spliterator.ORDERED)); 114 } 115 assertConcatContent(Spliterator<T> sp, boolean ordered, Spliterator<T> expected)116 private <T> void assertConcatContent(Spliterator<T> sp, boolean ordered, Spliterator<T> expected) { 117 // concat stream cannot guarantee uniqueness 118 assertFalse(sp.hasCharacteristics(Spliterator.DISTINCT), scenario); 119 // concat stream cannot guarantee sorted 120 assertFalse(sp.hasCharacteristics(Spliterator.SORTED), scenario); 121 // concat stream is ordered if both are ordered 122 assertEquals(sp.hasCharacteristics(Spliterator.ORDERED), ordered, scenario); 123 124 // Verify elements 125 if (ordered) { 126 assertEquals(toBoxedList(sp), 127 toBoxedList(expected), 128 scenario); 129 } else { 130 assertEquals(toBoxedMultiset(sp), 131 toBoxedMultiset(expected), 132 scenario); 133 } 134 } 135 assertRefConcat(Stream<Integer> s1, Stream<Integer> s2, boolean parallel, boolean ordered)136 private void assertRefConcat(Stream<Integer> s1, Stream<Integer> s2, boolean parallel, boolean ordered) { 137 Stream<Integer> result = Stream.concat(s1, s2); 138 assertEquals(result.isParallel(), parallel); 139 assertConcatContent(result.spliterator(), ordered, expected.spliterator()); 140 } 141 assertIntConcat(Stream<Integer> s1, Stream<Integer> s2, boolean parallel, boolean ordered)142 private void assertIntConcat(Stream<Integer> s1, Stream<Integer> s2, boolean parallel, boolean ordered) { 143 IntStream result = IntStream.concat(s1.mapToInt(Integer::intValue), 144 s2.mapToInt(Integer::intValue)); 145 assertEquals(result.isParallel(), parallel); 146 assertConcatContent(result.spliterator(), ordered, 147 expected.stream().mapToInt(Integer::intValue).spliterator()); 148 } 149 assertLongConcat(Stream<Integer> s1, Stream<Integer> s2, boolean parallel, boolean ordered)150 private void assertLongConcat(Stream<Integer> s1, Stream<Integer> s2, boolean parallel, boolean ordered) { 151 LongStream result = LongStream.concat(s1.mapToLong(Integer::longValue), 152 s2.mapToLong(Integer::longValue)); 153 assertEquals(result.isParallel(), parallel); 154 assertConcatContent(result.spliterator(), ordered, 155 expected.stream().mapToLong(Integer::longValue).spliterator()); 156 } 157 assertDoubleConcat(Stream<Integer> s1, Stream<Integer> s2, boolean parallel, boolean ordered)158 private void assertDoubleConcat(Stream<Integer> s1, Stream<Integer> s2, boolean parallel, boolean ordered) { 159 DoubleStream result = DoubleStream.concat(s1.mapToDouble(Integer::doubleValue), 160 s2.mapToDouble(Integer::doubleValue)); 161 assertEquals(result.isParallel(), parallel); 162 assertConcatContent(result.spliterator(), ordered, 163 expected.stream().mapToDouble(Integer::doubleValue).spliterator()); 164 } 165 testRefConcat()166 public void testRefConcat() { 167 // sequential + sequential -> sequential 168 assertRefConcat(c1.stream(), c2.stream(), false, true); 169 // parallel + parallel -> parallel 170 assertRefConcat(c1.parallelStream(), c2.parallelStream(), true, true); 171 // sequential + parallel -> parallel 172 assertRefConcat(c1.stream(), c2.parallelStream(), true, true); 173 // parallel + sequential -> parallel 174 assertRefConcat(c1.parallelStream(), c2.stream(), true, true); 175 176 // not ordered 177 assertRefConcat(c1.stream().unordered(), c2.stream(), false, false); 178 assertRefConcat(c1.stream(), c2.stream().unordered(), false, false); 179 assertRefConcat(c1.parallelStream().unordered(), c2.stream().unordered(), true, false); 180 } 181 testIntConcat()182 public void testIntConcat() { 183 // sequential + sequential -> sequential 184 assertIntConcat(c1.stream(), c2.stream(), false, true); 185 // parallel + parallel -> parallel 186 assertIntConcat(c1.parallelStream(), c2.parallelStream(), true, true); 187 // sequential + parallel -> parallel 188 assertIntConcat(c1.stream(), c2.parallelStream(), true, true); 189 // parallel + sequential -> parallel 190 assertIntConcat(c1.parallelStream(), c2.stream(), true, true); 191 192 // not ordered 193 assertIntConcat(c1.stream().unordered(), c2.stream(), false, false); 194 assertIntConcat(c1.stream(), c2.stream().unordered(), false, false); 195 assertIntConcat(c1.parallelStream().unordered(), c2.stream().unordered(), true, false); 196 } 197 testLongConcat()198 public void testLongConcat() { 199 // sequential + sequential -> sequential 200 assertLongConcat(c1.stream(), c2.stream(), false, true); 201 // parallel + parallel -> parallel 202 assertLongConcat(c1.parallelStream(), c2.parallelStream(), true, true); 203 // sequential + parallel -> parallel 204 assertLongConcat(c1.stream(), c2.parallelStream(), true, true); 205 // parallel + sequential -> parallel 206 assertLongConcat(c1.parallelStream(), c2.stream(), true, true); 207 208 // not ordered 209 assertLongConcat(c1.stream().unordered(), c2.stream(), false, false); 210 assertLongConcat(c1.stream(), c2.stream().unordered(), false, false); 211 assertLongConcat(c1.parallelStream().unordered(), c2.stream().unordered(), true, false); 212 } 213 testDoubleConcat()214 public void testDoubleConcat() { 215 // sequential + sequential -> sequential 216 assertDoubleConcat(c1.stream(), c2.stream(), false, true); 217 // parallel + parallel -> parallel 218 assertDoubleConcat(c1.parallelStream(), c2.parallelStream(), true, true); 219 // sequential + parallel -> parallel 220 assertDoubleConcat(c1.stream(), c2.parallelStream(), true, true); 221 // parallel + sequential -> parallel 222 assertDoubleConcat(c1.parallelStream(), c2.stream(), true, true); 223 224 // not ordered 225 assertDoubleConcat(c1.stream().unordered(), c2.stream(), false, false); 226 assertDoubleConcat(c1.stream(), c2.stream().unordered(), false, false); 227 assertDoubleConcat(c1.parallelStream().unordered(), c2.stream().unordered(), true, false); 228 } 229 } 230