提交 dca3f55a 编写于 作者: P psandoz

8024405: Spliterators.spliterator should support CONCURRENT characteristic

Reviewed-by: martin
上级 5347d042
......@@ -539,7 +539,7 @@ public interface Spliterator<T> {
* Spliterator is expected to have a documented policy concerning the impact
* of modifications during traversal.
*
* <p>A top-level Spliterator should not report {@code CONCURRENT} and
* <p>A top-level Spliterator should not report both {@code CONCURRENT} and
* {@code SIZED}, since the finite size, if known, may change if the source
* is concurrently modified during traversal. Such a Spliterator is
* inconsistent and no guarantees can be made about any computation using
......
......@@ -409,16 +409,16 @@ public final class Spliterators {
*
* @param <T> Type of elements
* @param c The collection
* @param additionalCharacteristics Additional spliterator characteristics
* of this spliterator's source or elements beyond {@code SIZED} and
* {@code SUBSIZED} which are are always reported
* @param characteristics Characteristics of this spliterator's source or
* elements. The characteristics {@code SIZED} and {@code SUBSIZED}
* are additionally reported unless {@code CONCURRENT} is supplied.
* @return A spliterator from an iterator
* @throws NullPointerException if the given collection is {@code null}
*/
public static <T> Spliterator<T> spliterator(Collection<? extends T> c,
int additionalCharacteristics) {
int characteristics) {
return new IteratorSpliterator<>(Objects.requireNonNull(c),
additionalCharacteristics);
characteristics);
}
/**
......@@ -439,17 +439,17 @@ public final class Spliterators {
* @param iterator The iterator for the source
* @param size The number of elements in the source, to be reported as
* initial {@code estimateSize}
* @param additionalCharacteristics Additional spliterator characteristics
* of this spliterator's source or elements beyond {@code SIZED} and
* {@code SUBSIZED} which are are always reported
* @param characteristics Characteristics of this spliterator's source or
* elements. The characteristics {@code SIZED} and {@code SUBSIZED}
* are additionally reported unless {@code CONCURRENT} is supplied.
* @return A spliterator from an iterator
* @throws NullPointerException if the given iterator is {@code null}
*/
public static <T> Spliterator<T> spliterator(Iterator<? extends T> iterator,
long size,
int additionalCharacteristics) {
int characteristics) {
return new IteratorSpliterator<>(Objects.requireNonNull(iterator), size,
additionalCharacteristics);
characteristics);
}
/**
......@@ -467,7 +467,7 @@ public final class Spliterators {
*
* @param <T> Type of elements
* @param iterator The iterator for the source
* @param characteristics Properties of this spliterator's source
* @param characteristics Characteristics of this spliterator's source
* or elements ({@code SIZED} and {@code SUBSIZED}, if supplied, are
* ignored and are not reported.)
* @return A spliterator from an iterator
......@@ -496,17 +496,17 @@ public final class Spliterators {
* @param iterator The iterator for the source
* @param size The number of elements in the source, to be reported as
* initial {@code estimateSize}.
* @param additionalCharacteristics Additional spliterator characteristics
* of this spliterator's source or elements beyond {@code SIZED} and
* {@code SUBSIZED} which are are always reported
* @param characteristics Characteristics of this spliterator's source or
* elements. The characteristics {@code SIZED} and {@code SUBSIZED}
* are additionally reported unless {@code CONCURRENT} is supplied.
* @return A spliterator from an iterator
* @throws NullPointerException if the given iterator is {@code null}
*/
public static Spliterator.OfInt spliterator(PrimitiveIterator.OfInt iterator,
long size,
int additionalCharacteristics) {
int characteristics) {
return new IntIteratorSpliterator(Objects.requireNonNull(iterator),
size, additionalCharacteristics);
size, characteristics);
}
/**
......@@ -524,7 +524,7 @@ public final class Spliterators {
* operated on after the spliterator is returned.
*
* @param iterator The iterator for the source
* @param characteristics Properties of this spliterator's source
* @param characteristics Characteristics of this spliterator's source
* or elements ({@code SIZED} and {@code SUBSIZED}, if supplied, are
* ignored and are not reported.)
* @return A spliterator from an iterator
......@@ -553,17 +553,17 @@ public final class Spliterators {
* @param iterator The iterator for the source
* @param size The number of elements in the source, to be reported as
* initial {@code estimateSize}.
* @param additionalCharacteristics Additional spliterator characteristics
* of this spliterator's source or elements beyond {@code SIZED} and
* {@code SUBSIZED} which are are always reported
* @param characteristics Characteristics of this spliterator's source or
* elements. The characteristics {@code SIZED} and {@code SUBSIZED}
* are additionally reported unless {@code CONCURRENT} is supplied.
* @return A spliterator from an iterator
* @throws NullPointerException if the given iterator is {@code null}
*/
public static Spliterator.OfLong spliterator(PrimitiveIterator.OfLong iterator,
long size,
int additionalCharacteristics) {
int characteristics) {
return new LongIteratorSpliterator(Objects.requireNonNull(iterator),
size, additionalCharacteristics);
size, characteristics);
}
/**
......@@ -581,7 +581,7 @@ public final class Spliterators {
* operated on after the spliterator is returned.
*
* @param iterator The iterator for the source
* @param characteristics Properties of this spliterator's source
* @param characteristics Characteristics of this spliterator's source
* or elements ({@code SIZED} and {@code SUBSIZED}, if supplied, are
* ignored and are not reported.)
* @return A spliterator from an iterator
......@@ -610,17 +610,17 @@ public final class Spliterators {
* @param iterator The iterator for the source
* @param size The number of elements in the source, to be reported as
* initial {@code estimateSize}
* @param additionalCharacteristics Additional spliterator characteristics
* of this spliterator's source or elements beyond {@code SIZED} and
* {@code SUBSIZED} which are are always reported
* @param characteristics Characteristics of this spliterator's source or
* elements. The characteristics {@code SIZED} and {@code SUBSIZED}
* are additionally reported unless {@code CONCURRENT} is supplied.
* @return A spliterator from an iterator
* @throws NullPointerException if the given iterator is {@code null}
*/
public static Spliterator.OfDouble spliterator(PrimitiveIterator.OfDouble iterator,
long size,
int additionalCharacteristics) {
int characteristics) {
return new DoubleIteratorSpliterator(Objects.requireNonNull(iterator),
size, additionalCharacteristics);
size, characteristics);
}
/**
......@@ -638,7 +638,7 @@ public final class Spliterators {
* operated on after the spliterator is returned.
*
* @param iterator The iterator for the source
* @param characteristics Properties of this spliterator's source
* @param characteristics Characteristics of this spliterator's source
* or elements ({@code SIZED} and {@code SUBSIZED}, if supplied, are
* ignored and are not reported.)
* @return A spliterator from an iterator
......@@ -1710,7 +1710,9 @@ public final class Spliterators {
public IteratorSpliterator(Collection<? extends T> collection, int characteristics) {
this.collection = collection;
this.it = null;
this.characteristics = characteristics | Spliterator.SIZED | Spliterator.SUBSIZED;
this.characteristics = (characteristics & Spliterator.CONCURRENT) == 0
? characteristics | Spliterator.SIZED | Spliterator.SUBSIZED
: characteristics;
}
/**
......@@ -1727,7 +1729,9 @@ public final class Spliterators {
this.collection = null;
this.it = iterator;
this.est = size;
this.characteristics = characteristics | Spliterator.SIZED | Spliterator.SUBSIZED;
this.characteristics = (characteristics & Spliterator.CONCURRENT) == 0
? characteristics | Spliterator.SIZED | Spliterator.SUBSIZED
: characteristics;
}
/**
......@@ -1857,7 +1861,9 @@ public final class Spliterators {
public IntIteratorSpliterator(PrimitiveIterator.OfInt iterator, long size, int characteristics) {
this.it = iterator;
this.est = size;
this.characteristics = characteristics | Spliterator.SIZED | Spliterator.SUBSIZED;
this.characteristics = (characteristics & Spliterator.CONCURRENT) == 0
? characteristics | Spliterator.SIZED | Spliterator.SUBSIZED
: characteristics;
}
/**
......@@ -1949,7 +1955,9 @@ public final class Spliterators {
public LongIteratorSpliterator(PrimitiveIterator.OfLong iterator, long size, int characteristics) {
this.it = iterator;
this.est = size;
this.characteristics = characteristics | Spliterator.SIZED | Spliterator.SUBSIZED;
this.characteristics = (characteristics & Spliterator.CONCURRENT) == 0
? characteristics | Spliterator.SIZED | Spliterator.SUBSIZED
: characteristics;
}
/**
......@@ -2041,7 +2049,9 @@ public final class Spliterators {
public DoubleIteratorSpliterator(PrimitiveIterator.OfDouble iterator, long size, int characteristics) {
this.it = iterator;
this.est = size;
this.characteristics = characteristics | Spliterator.SIZED | Spliterator.SUBSIZED;
this.characteristics = (characteristics & Spliterator.CONCURRENT) == 0
? characteristics | Spliterator.SIZED | Spliterator.SUBSIZED
: characteristics;
}
/**
......
......@@ -23,7 +23,7 @@
/**
* @test
* @bug 8020156 8020009 8022326 8012913
* @bug 8020156 8020009 8022326 8012913 8024405
* @run testng SpliteratorCharacteristics
*/
......@@ -36,21 +36,150 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.PrimitiveIterator;
import java.util.Set;
import java.util.SortedMap;
import java.util.SortedSet;
import java.util.Spliterator;
import java.util.Spliterators;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.concurrent.ConcurrentSkipListMap;
import java.util.concurrent.ConcurrentSkipListSet;
import java.util.function.Supplier;
import java.util.stream.DoubleStream;
import java.util.stream.IntStream;
import java.util.stream.LongStream;
import static org.testng.Assert.*;
@Test
public class SpliteratorCharacteristics {
public void testSpliteratorFromCollection() {
List<Integer> l = Arrays.asList(1, 2, 3, 4);
{
Spliterator<?> s = Spliterators.spliterator(l, 0);
assertCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED);
assertHasNotCharacteristics(s, Spliterator.CONCURRENT);
}
{
Spliterator<?> s = Spliterators.spliterator(l, Spliterator.CONCURRENT);
assertHasNotCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED);
assertCharacteristics(s, Spliterator.CONCURRENT);
}
{
Spliterator<?> s = Spliterators.spliterator(l.iterator( ), 1, 0);
assertCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED);
assertHasNotCharacteristics(s, Spliterator.CONCURRENT);
}
{
Spliterator<?> s = Spliterators.spliterator(l.iterator( ), 1, Spliterator.CONCURRENT);
assertHasNotCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED);
assertCharacteristics(s, Spliterator.CONCURRENT);
}
{
Spliterator<?> s = Spliterators.spliteratorUnknownSize(l.iterator( ), 0);
assertHasNotCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED);
}
{
Spliterator<?> s = Spliterators.spliteratorUnknownSize(
l.iterator(), Spliterator.SIZED | Spliterator.SUBSIZED);
assertHasNotCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED);
}
}
public void testSpliteratorOfIntFromIterator() {
Supplier<PrimitiveIterator.OfInt> si = () -> IntStream.of(1, 2, 3, 4).iterator();
{
Spliterator<?> s = Spliterators.spliterator(si.get(), 1, 0);
assertCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED);
assertHasNotCharacteristics(s, Spliterator.CONCURRENT);
}
{
Spliterator<?> s = Spliterators.spliterator(si.get(), 1, Spliterator.CONCURRENT);
assertHasNotCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED);
assertCharacteristics(s, Spliterator.CONCURRENT);
}
{
Spliterator<?> s = Spliterators.spliteratorUnknownSize(si.get(), 0);
assertHasNotCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED);
}
{
Spliterator<?> s = Spliterators.spliteratorUnknownSize(
si.get(), Spliterator.SIZED | Spliterator.SUBSIZED);
assertHasNotCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED);
}
}
public void testSpliteratorOfLongFromIterator() {
Supplier<PrimitiveIterator.OfLong> si = () -> LongStream.of(1, 2, 3, 4).iterator();
{
Spliterator<?> s = Spliterators.spliterator(si.get(), 1, 0);
assertCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED);
assertHasNotCharacteristics(s, Spliterator.CONCURRENT);
}
{
Spliterator<?> s = Spliterators.spliterator(si.get(), 1, Spliterator.CONCURRENT);
assertHasNotCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED);
assertCharacteristics(s, Spliterator.CONCURRENT);
}
{
Spliterator<?> s = Spliterators.spliteratorUnknownSize(si.get(), 0);
assertHasNotCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED);
}
{
Spliterator<?> s = Spliterators.spliteratorUnknownSize(
si.get(), Spliterator.SIZED | Spliterator.SUBSIZED);
assertHasNotCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED);
}
}
public void testSpliteratorOfDoubleFromIterator() {
Supplier<PrimitiveIterator.OfDouble> si = () -> DoubleStream.of(1, 2, 3, 4).iterator();
{
Spliterator<?> s = Spliterators.spliterator(si.get(), 1, 0);
assertCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED);
assertHasNotCharacteristics(s, Spliterator.CONCURRENT);
}
{
Spliterator<?> s = Spliterators.spliterator(si.get(), 1, Spliterator.CONCURRENT);
assertHasNotCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED);
assertCharacteristics(s, Spliterator.CONCURRENT);
}
{
Spliterator<?> s = Spliterators.spliteratorUnknownSize(si.get(), 0);
assertHasNotCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED);
}
{
Spliterator<?> s = Spliterators.spliteratorUnknownSize(
si.get(), Spliterator.SIZED | Spliterator.SUBSIZED);
assertHasNotCharacteristics(s, Spliterator.SIZED | Spliterator.SUBSIZED);
}
}
//
public void testHashMap() {
assertMapCharacteristics(new HashMap<>(),
Spliterator.SIZED | Spliterator.DISTINCT);
......@@ -199,7 +328,16 @@ public class SpliteratorCharacteristics {
}
void assertCharacteristics(Collection<?> c, int expectedCharacteristics) {
assertTrue(c.spliterator().hasCharacteristics(expectedCharacteristics),
assertCharacteristics(c.spliterator(), expectedCharacteristics);
}
void assertCharacteristics(Spliterator<?> s, int expectedCharacteristics) {
assertTrue(s.hasCharacteristics(expectedCharacteristics),
"Spliterator characteristics");
}
void assertHasNotCharacteristics(Spliterator<?> s, int expectedCharacteristics) {
assertFalse(s.hasCharacteristics(expectedCharacteristics),
"Spliterator characteristics");
}
......
......@@ -1159,7 +1159,7 @@ public class SpliteratorTraversingAndSplittingTest {
List<T> dest = new ArrayList<>();
spliterator = supplier.get();
assertSpliterator(spliterator);
assertRootSpliterator(spliterator);
// verify splitting with forEach
visit(depth, 0, dest, spliterator, boxingAdapter, spliterator.characteristics(), false);
......@@ -1234,7 +1234,7 @@ public class SpliteratorTraversingAndSplittingTest {
UnaryOperator<Consumer<T>> boxingAdapter) {
Spliterator<T> s = supplier.get();
boolean isOrdered = s.hasCharacteristics(Spliterator.ORDERED);
assertSpliterator(s);
assertRootSpliterator(s);
List<T> splits = new ArrayList<>();
Consumer<T> c = boxingAdapter.apply(splits::add);
......@@ -1326,6 +1326,13 @@ public class SpliteratorTraversingAndSplittingTest {
}
}
private static void assertRootSpliterator(Spliterator<?> s) {
assertFalse(s.hasCharacteristics(Spliterator.SIZED | Spliterator.CONCURRENT),
"Root spliterator should not be SIZED and CONCURRENT");
assertSpliterator(s);
}
private static void assertSpliterator(Spliterator<?> s, int rootCharacteristics) {
if ((rootCharacteristics & Spliterator.SUBSIZED) != 0) {
assertTrue(s.hasCharacteristics(Spliterator.SUBSIZED),
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册