提交 dd860156 编写于 作者: M mduigou

8015315: Stream.concat methods

Reviewed-by: psandoz, mduigou
Contributed-by: brian.goetz@oracle.com, henry.jen@oracle.com
上级 477f1cc7
......@@ -746,4 +746,26 @@ public interface DoubleStream extends BaseStream<Double, DoubleStream> {
return StreamSupport.doubleStream(
new StreamSpliterators.InfiniteSupplyingSpliterator.OfDouble(Long.MAX_VALUE, s));
}
/**
* Creates a lazy concatenated {@code DoubleStream} whose elements are all the
* elements of a first {@code DoubleStream} succeeded by all the elements of the
* second {@code DoubleStream}. The resulting stream is ordered if both
* of the input streams are ordered, and parallel if either of the input
* streams is parallel.
*
* @param a the first stream
* @param b the second stream to concatenate on to end of the first stream
* @return the concatenation of the two streams
*/
public static DoubleStream concat(DoubleStream a, DoubleStream b) {
Objects.requireNonNull(a);
Objects.requireNonNull(b);
Spliterator.OfDouble split = new Streams.ConcatSpliterator.OfDouble(
a.spliterator(), b.spliterator());
return (a.isParallel() || b.isParallel())
? StreamSupport.doubleParallelStream(split)
: StreamSupport.doubleStream(split);
}
}
......@@ -800,4 +800,26 @@ public interface IntStream extends BaseStream<Integer, IntStream> {
new Streams.RangeIntSpliterator(startInclusive, endInclusive, true));
}
}
/**
* Creates a lazy concatenated {@code IntStream} whose elements are all the
* elements of a first {@code IntStream} succeeded by all the elements of the
* second {@code IntStream}. The resulting stream is ordered if both
* of the input streams are ordered, and parallel if either of the input
* streams is parallel.
*
* @param a the first stream
* @param b the second stream to concatenate on to end of the first stream
* @return the concatenation of the two streams
*/
public static IntStream concat(IntStream a, IntStream b) {
Objects.requireNonNull(a);
Objects.requireNonNull(b);
Spliterator.OfInt split = new Streams.ConcatSpliterator.OfInt(
a.spliterator(), b.spliterator());
return (a.isParallel() || b.isParallel())
? StreamSupport.intParallelStream(split)
: StreamSupport.intStream(split);
}
}
......@@ -765,10 +765,8 @@ public interface LongStream extends BaseStream<Long, LongStream> {
// Split the range in two and concatenate
// Note: if the range is [Long.MIN_VALUE, Long.MAX_VALUE) then
// the lower range, [Long.MIN_VALUE, 0) will be further split in two
// long m = startInclusive + Long.divideUnsigned(endExclusive - startInclusive, 2) + 1;
// return Streams.concat(range(startInclusive, m), range(m, endExclusive));
// This is temporary until Streams.concat is supported
throw new UnsupportedOperationException();
long m = startInclusive + Long.divideUnsigned(endExclusive - startInclusive, 2) + 1;
return concat(range(startInclusive, m), range(m, endExclusive));
} else {
return StreamSupport.longStream(
new Streams.RangeLongSpliterator(startInclusive, endExclusive, false));
......@@ -801,13 +799,33 @@ public interface LongStream extends BaseStream<Long, LongStream> {
// Note: if the range is [Long.MIN_VALUE, Long.MAX_VALUE] then
// the lower range, [Long.MIN_VALUE, 0), and upper range,
// [0, Long.MAX_VALUE], will both be further split in two
// long m = startInclusive + Long.divideUnsigned(endInclusive - startInclusive, 2) + 1;
// return Streams.concat(range(startInclusive, m), rangeClosed(m, endInclusive));
// This is temporary until Streams.concat is supported
throw new UnsupportedOperationException();
long m = startInclusive + Long.divideUnsigned(endInclusive - startInclusive, 2) + 1;
return concat(range(startInclusive, m), rangeClosed(m, endInclusive));
} else {
return StreamSupport.longStream(
new Streams.RangeLongSpliterator(startInclusive, endInclusive, true));
}
}
/**
* Creates a lazy concatenated {@code LongStream} whose elements are all the
* elements of a first {@code LongStream} succeeded by all the elements of the
* second {@code LongStream}. The resulting stream is ordered if both
* of the input streams are ordered, and parallel if either of the input
* streams is parallel.
*
* @param a the first stream
* @param b the second stream to concatenate on to end of the first stream
* @return the concatenation of the two streams
*/
public static LongStream concat(LongStream a, LongStream b) {
Objects.requireNonNull(a);
Objects.requireNonNull(b);
Spliterator.OfLong split = new Streams.ConcatSpliterator.OfLong(
a.spliterator(), b.spliterator());
return (a.isParallel() || b.isParallel())
? StreamSupport.longParallelStream(split)
: StreamSupport.longStream(split);
}
}
......@@ -883,4 +883,29 @@ public interface Stream<T> extends BaseStream<T, Stream<T>> {
return StreamSupport.stream(
new StreamSpliterators.InfiniteSupplyingSpliterator.OfRef<>(Long.MAX_VALUE, s));
}
/**
* Creates a lazy concatenated {@code Stream} whose elements are all the
* elements of a first {@code Stream} succeeded by all the elements of the
* second {@code Stream}. The resulting stream is ordered if both
* of the input streams are ordered, and parallel if either of the input
* streams is parallel.
*
* @param <T> The type of stream elements
* @param a the first stream
* @param b the second stream to concatenate on to end of the first
* stream
* @return the concatenation of the two input streams
*/
public static <T> Stream<T> concat(Stream<? extends T> a, Stream<? extends T> b) {
Objects.requireNonNull(a);
Objects.requireNonNull(b);
@SuppressWarnings("unchecked")
Spliterator<T> split = new Streams.ConcatSpliterator.OfRef<>(
(Spliterator<T>) a.spliterator(), (Spliterator<T>) b.spliterator());
return (a.isParallel() || b.isParallel())
? StreamSupport.parallelStream(split)
: StreamSupport.stream(split);
}
}
......@@ -43,7 +43,7 @@ import java.util.function.LongConsumer;
*
* @since 1.8
*/
class Streams {
final class Streams {
private Streams() {
throw new Error("no instances");
......@@ -670,4 +670,147 @@ class Streams {
}
}
}
abstract static class ConcatSpliterator<T, T_SPLITR extends Spliterator<T>>
implements Spliterator<T> {
protected final T_SPLITR aSpliterator;
protected final T_SPLITR bSpliterator;
// True when no split has occurred, otherwise false
boolean beforeSplit;
// Never read after splitting
final boolean unsized;
public ConcatSpliterator(T_SPLITR aSpliterator, T_SPLITR bSpliterator) {
this.aSpliterator = aSpliterator;
this.bSpliterator = bSpliterator;
beforeSplit = true;
// The spliterator is unsized before splitting if a and b are
// sized and the sum of the estimates overflows
unsized = aSpliterator.hasCharacteristics(SIZED)
&& aSpliterator.hasCharacteristics(SIZED)
&& aSpliterator.estimateSize() + bSpliterator.estimateSize() < 0;
}
@Override
public T_SPLITR trySplit() {
T_SPLITR ret = beforeSplit ? aSpliterator : (T_SPLITR) bSpliterator.trySplit();
beforeSplit = false;
return ret;
}
@Override
public boolean tryAdvance(Consumer<? super T> consumer) {
boolean hasNext;
if (beforeSplit) {
hasNext = aSpliterator.tryAdvance(consumer);
if (!hasNext) {
beforeSplit = false;
hasNext = bSpliterator.tryAdvance(consumer);
}
}
else
hasNext = bSpliterator.tryAdvance(consumer);
return hasNext;
}
@Override
public void forEachRemaining(Consumer<? super T> consumer) {
if (beforeSplit)
aSpliterator.forEachRemaining(consumer);
bSpliterator.forEachRemaining(consumer);
}
@Override
public long estimateSize() {
if (beforeSplit) {
// If one or both estimates are Long.MAX_VALUE then the sum
// will either be Long.MAX_VALUE or overflow to a negative value
long size = aSpliterator.estimateSize() + bSpliterator.estimateSize();
return (size >= 0) ? size : Long.MAX_VALUE;
}
else {
return bSpliterator.estimateSize();
}
}
@Override
public int characteristics() {
if (beforeSplit) {
// Concatenation loses DISTINCT and SORTED characteristics
return aSpliterator.characteristics() & bSpliterator.characteristics()
& ~(Spliterator.DISTINCT | Spliterator.SORTED
| (unsized ? Spliterator.SIZED | Spliterator.SUBSIZED : 0));
}
else {
return bSpliterator.characteristics();
}
}
@Override
public Comparator<? super T> getComparator() {
if (beforeSplit)
throw new IllegalStateException();
return bSpliterator.getComparator();
}
static class OfRef<T> extends ConcatSpliterator<T, Spliterator<T>> {
OfRef(Spliterator<T> aSpliterator, Spliterator<T> bSpliterator) {
super(aSpliterator, bSpliterator);
}
}
private static abstract class OfPrimitive<T, T_CONS, T_SPLITR extends Spliterator.OfPrimitive<T, T_CONS, T_SPLITR>>
extends ConcatSpliterator<T, T_SPLITR>
implements Spliterator.OfPrimitive<T, T_CONS, T_SPLITR> {
private OfPrimitive(T_SPLITR aSpliterator, T_SPLITR bSpliterator) {
super(aSpliterator, bSpliterator);
}
@Override
public boolean tryAdvance(T_CONS action) {
boolean hasNext;
if (beforeSplit) {
hasNext = aSpliterator.tryAdvance(action);
if (!hasNext) {
beforeSplit = false;
hasNext = bSpliterator.tryAdvance(action);
}
}
else
hasNext = bSpliterator.tryAdvance(action);
return hasNext;
}
@Override
public void forEachRemaining(T_CONS action) {
if (beforeSplit)
aSpliterator.forEachRemaining(action);
bSpliterator.forEachRemaining(action);
}
}
static class OfInt
extends ConcatSpliterator.OfPrimitive<Integer, IntConsumer, Spliterator.OfInt>
implements Spliterator.OfInt {
OfInt(Spliterator.OfInt aSpliterator, Spliterator.OfInt bSpliterator) {
super(aSpliterator, bSpliterator);
}
}
static class OfLong
extends ConcatSpliterator.OfPrimitive<Long, LongConsumer, Spliterator.OfLong>
implements Spliterator.OfLong {
OfLong(Spliterator.OfLong aSpliterator, Spliterator.OfLong bSpliterator) {
super(aSpliterator, bSpliterator);
}
}
static class OfDouble
extends ConcatSpliterator.OfPrimitive<Double, DoubleConsumer, Spliterator.OfDouble>
implements Spliterator.OfDouble {
OfDouble(Spliterator.OfDouble aSpliterator, Spliterator.OfDouble bSpliterator) {
super(aSpliterator, bSpliterator);
}
}
}
}
......@@ -360,35 +360,26 @@ public class LambdaTestHelpers {
private static<T> Map<T, Integer> toBoxedMultiset(Iterator<T> it) {
Map<Object, Integer> result = new HashMap<>();
it.forEachRemaining(new OmnivorousConsumer<T>() {
@Override
public void accept(T t) {
add(t);
}
@Override
public void accept(int value) {
add(value);
}
it.forEachRemaining(toBoxingConsumer(o -> {
if (result.containsKey(o))
result.put(o, result.get(o) + 1);
else
result.put(o, 1);
}));
@Override
public void accept(long value) {
add(value);
}
return (Map<T, Integer>) result;
}
@Override
public void accept(double value) {
add(value);
}
@SuppressWarnings("unchecked")
public static<T> Map<T, Integer> toBoxedMultiset(Spliterator<T> it) {
Map<Object, Integer> result = new HashMap<>();
void add(Object o) {
it.forEachRemaining(toBoxingConsumer(o -> {
if (result.containsKey(o))
result.put(o, result.get(o) + 1);
else
result.put(o, 1);
}
});
}));
return (Map<T, Integer>) result;
}
......
/*
* 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 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.*;
public class ConcatOpTest extends OpTestCase {
// Sanity to make sure all type of stream source works
@Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
public void testOpsSequential(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)));
}
}
/*
* 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);
}
}
......@@ -226,116 +226,114 @@ public class RangeTest extends OpTestCase {
assertEquals(first, LongStream.iterate(0, i -> i + 1).parallel().filter(i -> i > 10000).findFirst().getAsLong());
}
// Enable when Stream.concat is present and range implementations are
// updated to use that
// 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);
// }
// }
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);
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册