提交 d497139d 编写于 作者: B briangoetz

8010096: Initial java.util.Spliterator putback

Reviewed-by: mduigou, alanb, chegar, darcy
Contributed-by: NPaul Sandoz &lt;paul.sandoz@oracle.com&gt;, Brian Goetz &lt;brian.goetz@oracle.com&gt;, Doug Lea <dl@cs.oswego.edu>
上级 4d47c8ee
......@@ -851,6 +851,11 @@ public class EventSetImpl extends ArrayList<Event> implements EventSet {
}
}
@Override
public Spliterator<Event> spliterator() {
return Spliterators.spliterator(this, Spliterator.DISTINCT);
}
/* below make this unmodifiable */
public boolean add(Event o){
......
......@@ -22,26 +22,55 @@
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang;
import java.util.Iterator;
import java.util.Objects;
import java.util.function.Consumer;
/**
* Implementing this interface allows an object to be the target of
* the "foreach" statement.
* the "for-each loop" statement. See
* <strong>
* <a href="{@docRoot}/../technotes/guides/language/foreach.html">For-each Loop</a>
* </strong>
*
* @param <T> the type of elements returned by the iterator
*
* @since 1.5
* @jls 14.14.2 The enhanced for statement
*/
@FunctionalInterface
public interface Iterable<T> {
/**
* Returns an iterator over a set of elements of type T.
* Returns an iterator over elements of type {@code T}.
*
* @return an Iterator.
*/
Iterator<T> iterator();
/**
* Performs the given action on the contents of the {@code Iterable}, in the
* order elements occur when iterating, until all elements have been
* processed or the action throws an exception. Errors or runtime
* exceptions thrown by the action are relayed to the caller.
*
* @implSpec
* <p>The default implementation behaves as if:
* <pre>{@code
* for (T t : this)
* action.accept(t);
* }</pre>
*
* @param action The action to be performed for each element
* @throws NullPointerException if the specified action is null
* @since 1.8
*/
default void forEach(Consumer<? super T> action) {
Objects.requireNonNull(action);
for (T t : this) {
action.accept(t);
}
}
}
/*
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 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
......@@ -3518,6 +3518,11 @@ public class Arrays {
public boolean contains(Object o) {
return indexOf(o) != -1;
}
@Override
public Spliterator<E> spliterator() {
return Spliterators.spliterator(a, Spliterator.ORDERED);
}
}
/**
......@@ -4300,4 +4305,167 @@ public class Arrays {
buf.append(']');
dejaVu.remove(a);
}
/**
* Creates a {@link Spliterator} covering all of the specified array.
*
* <p>The spliterator reports {@link Spliterator#SIZED},
* {@link Spliterator#SUBSIZED}, {@link Spliterator#ORDERED}, and
* {@link Spliterator#IMMUTABLE}.
*
* @param <T> Type of elements
* @param array The array, assumed to be unmodified during use
* @return A spliterator from the array
* @throws NullPointerException if the specified array is {@code null}
* @since 1.8
*/
public static <T> Spliterator<T> spliterator(T[] array) {
return Spliterators.spliterator(array,
Spliterator.ORDERED | Spliterator.IMMUTABLE);
}
/**
* Creates a {@link Spliterator} covering the specified range of the
* specified array.
*
* <p>The spliterator reports {@link Spliterator#SIZED},
* {@link Spliterator#SUBSIZED}, {@link Spliterator#ORDERED}, and
* {@link Spliterator#IMMUTABLE}.
*
* @param <T> Type of elements
* @param array The array, assumed to be unmodified during use
* @param fromIndex The least index (inclusive) to cover
* @param toIndex One past the greatest index to cover
* @return A spliterator from the array
* @throws NullPointerException if the specified array is {@code null}
* @throws ArrayIndexOutOfBoundsException if {@code fromIndex} is negative,
* {@code toIndex} is less than {@code fromIndex}, or
* {@code toIndex} is greater than the array size
* @since 1.8
*/
public static <T> Spliterator<T> spliterator(T[] array, int fromIndex, int toIndex) {
return Spliterators.spliterator(array, fromIndex, toIndex,
Spliterator.ORDERED | Spliterator.IMMUTABLE);
}
/**
* Creates a {@link Spliterator.OfInt} covering all of the specified array.
*
* <p>The spliterator reports {@link Spliterator#SIZED},
* {@link Spliterator#SUBSIZED}, {@link Spliterator#ORDERED}, and
* {@link Spliterator#IMMUTABLE}.
*
* @param array The array, assumed to be unmodified during use
* @return A spliterator from the array
* @throws NullPointerException if the specified array is {@code null}
* @since 1.8
*/
public static Spliterator.OfInt spliterator(int[] array) {
return Spliterators.spliterator(array,
Spliterator.ORDERED | Spliterator.IMMUTABLE);
}
/**
* Creates a {@link Spliterator.OfInt} covering the specified range of the
* specified array.
*
* <p>The spliterator reports {@link Spliterator#SIZED},
* {@link Spliterator#SUBSIZED}, {@link Spliterator#ORDERED}, and
* {@link Spliterator#IMMUTABLE}.
*
* @param array The array, assumed to be unmodified during use
* @param fromIndex The least index (inclusive) to cover
* @param toIndex One past the greatest index to cover
* @return A spliterator from the array
* @throws NullPointerException if the specified array is {@code null}
* @throws ArrayIndexOutOfBoundsException if {@code fromIndex} is negative,
* {@code toIndex} is less than {@code fromIndex}, or
* {@code toIndex} is greater than the array size
* @since 1.8
*/
public static Spliterator.OfInt spliterator(int[] array, int fromIndex, int toIndex) {
return Spliterators.spliterator(array, fromIndex, toIndex,
Spliterator.ORDERED | Spliterator.IMMUTABLE);
}
/**
* Creates a {@link Spliterator.OfLong} covering all of the specified array.
*
* <p>The spliterator reports {@link Spliterator#SIZED},
* {@link Spliterator#SUBSIZED}, {@link Spliterator#ORDERED}, and
* {@link Spliterator#IMMUTABLE}.
*
* @param array The array, assumed to be unmodified during use
* @return A spliterator from the array
* @throws NullPointerException if the specified array is {@code null}
* @since 1.8
*/
public static Spliterator.OfLong spliterator(long[] array) {
return Spliterators.spliterator(array,
Spliterator.ORDERED | Spliterator.IMMUTABLE);
}
/**
* Creates a {@link Spliterator.OfLong} covering the specified range of the
* specified array.
*
* <p>The spliterator reports {@link Spliterator#SIZED},
* {@link Spliterator#SUBSIZED}, {@link Spliterator#ORDERED}, and
* {@link Spliterator#IMMUTABLE}.
*
* @param array The array, assumed to be unmodified during use
* @param fromIndex The least index (inclusive) to cover
* @param toIndex One past the greatest index to cover
* @return A spliterator from the array
* @throws NullPointerException if the specified array is {@code null}
* @throws ArrayIndexOutOfBoundsException if {@code fromIndex} is negative,
* {@code toIndex} is less than {@code fromIndex}, or
* {@code toIndex} is greater than the array size
* @since 1.8
*/
public static Spliterator.OfLong spliterator(long[] array, int fromIndex, int toIndex) {
return Spliterators.spliterator(array, fromIndex, toIndex,
Spliterator.ORDERED | Spliterator.IMMUTABLE);
}
/**
* Creates a {@link Spliterator.OfDouble} covering all of the specified
* array.
*
* <p>The spliterator reports {@link Spliterator#SIZED},
* {@link Spliterator#SUBSIZED}, {@link Spliterator#ORDERED}, and
* {@link Spliterator#IMMUTABLE}.
*
* @param array The array, assumed to be unmodified during use
* @return A spliterator from the array
* @throws NullPointerException if the specified array is {@code null}
* @since 1.8
*/
public static Spliterator.OfDouble spliterator(double[] array) {
return Spliterators.spliterator(array,
Spliterator.ORDERED | Spliterator.IMMUTABLE);
}
/**
* Creates a {@link Spliterator.OfDouble} covering the specified range of
* the specified array.
*
* <p>The spliterator reports {@link Spliterator#SIZED},
* {@link Spliterator#SUBSIZED}, {@link Spliterator#ORDERED}, and
* {@link Spliterator#IMMUTABLE}.
*
* @param array The array, assumed to be unmodified during use
* @param fromIndex The least index (inclusive) to cover
* @param toIndex One past the greatest index to cover
* @return A spliterator from the array
* @throws NullPointerException if the specified array is {@code null}
* @throws ArrayIndexOutOfBoundsException if {@code fromIndex} is negative,
* {@code toIndex} is less than {@code fromIndex}, or
* {@code toIndex} is greater than the array size
* @since 1.8
*/
public static Spliterator.OfDouble spliterator(double[] array, int fromIndex, int toIndex) {
return Spliterators.spliterator(array, fromIndex, toIndex,
Spliterator.ORDERED | Spliterator.IMMUTABLE);
}
}
/*
* Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 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
......@@ -104,6 +104,12 @@ package java.util;
* <a href="{@docRoot}/../technotes/guides/collections/index.html">
* Java Collections Framework</a>.
*
* @implSpec
* The default method implementations (inherited or otherwise) do not apply any
* synchronization protocol. If a {@code Collection} implementation has a
* specific synchronization protocol, then it must override default
* implementations to apply that protocol.
*
* @param <E> the type of elements in this collection
*
* @author Josh Bloch
......@@ -453,4 +459,28 @@ public interface Collection<E> extends Iterable<E> {
* @see Object#equals(Object)
*/
int hashCode();
/**
* Creates a {@link Spliterator} over the elements in this collection.
*
* <p>The {@code Spliterator} reports {@link Spliterator#SIZED}.
* Implementations should document the reporting of additional
* characteristic values.
*
* @implSpec
* The default implementation creates a
* <em><a href="Spliterator.html#binding">late-binding</a></em> spliterator
* from the collections's {@code Iterator}. The spliterator inherits the
* <em>fail-fast</em> properties of the collection's iterator.
*
* @implNote
* The created {@code Spliterator} additionally reports
* {@link Spliterator#SUBSIZED}.
*
* @return a {@code Spliterator} over the elements in this collection
* @since 1.8
*/
default Spliterator<E> spliterator() {
return Spliterators.spliterator(this, 0);
}
}
/*
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 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
......@@ -25,6 +25,8 @@
package java.util;
import java.util.function.Consumer;
/**
* An iterator over a collection. {@code Iterator} takes the place of
* {@link Enumeration} in the Java Collections Framework. Iterators
......@@ -75,6 +77,10 @@ public interface Iterator<E> {
* iteration is in progress in any way other than by calling this
* method.
*
* @implSpec
* The default implementation throws an instance of
* {@link UnsupportedOperationException} and performs no other action.
*
* @throws UnsupportedOperationException if the {@code remove}
* operation is not supported by this iterator
*
......@@ -83,5 +89,30 @@ public interface Iterator<E> {
* been called after the last call to the {@code next}
* method
*/
void remove();
default void remove() {
throw new UnsupportedOperationException("remove");
}
/**
* Performs the given action for each remaining element, in the order
* elements occur when iterating, until all elements have been processed or
* the action throws an exception. Errors or runtime exceptions thrown by
* the action are relayed to the caller.
*
* @implSpec
* <p>The default implementation behaves as if:
* <pre>{@code
* while (hasNext())
* action.accept(next());
* }</pre>
*
* @param action The action to be performed for each element
* @throws NullPointerException if the specified action is null
* @since 1.8
*/
default void forEachRemaining(Consumer<? super E> action) {
Objects.requireNonNull(action);
while (hasNext())
action.accept(next());
}
}
/*
* Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 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
......@@ -597,4 +597,30 @@ public interface List<E> extends Collection<E> {
* fromIndex &gt; toIndex</tt>)
*/
List<E> subList(int fromIndex, int toIndex);
/**
* Creates a {@link Spliterator} over the elements in this list.
*
* <p>The {@code Spliterator} reports {@link Spliterator#SIZED} and
* {@link Spliterator#ORDERED}. Implementations should document the
* reporting of additional characteristic values.
*
* @implSpec
* The default implementation creates a
* <em><a href="Spliterator.html#binding">late-binding</a></em> spliterator
* from the list's {@code Iterator}. The spliterator inherits the
* <em>fail-fast</em> properties of the collection's iterator.
*
* @implNote
* The created {@code Spliterator} additionally reports
* {@link Spliterator#SUBSIZED}.
*
* @return a {@code Spliterator} over the elements in this list
* @since 1.8
*/
@Override
default Spliterator<E> spliterator() {
return Spliterators.spliterator(this, Spliterator.ORDERED);
}
}
/*
* 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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;
import java.util.function.Consumer;
import java.util.function.DoubleConsumer;
import java.util.function.IntConsumer;
import java.util.function.LongConsumer;
/**
* A base type for primitive specializations of {@code Iterator}. Specialized
* subtypes are provided for {@link OfInt int}, {@link OfLong long}, and
* {@link OfDouble double} values.
*
* <p>The specialized subtype default implementations of {@link Iterator#next}
* and {@link Iterator#forEachRemaining(java.util.function.Consumer)} box
* primitive values to instances of their corresponding wrapper class. Such
* boxing may offset any advantages gained when using the primitive
* specializations. To avoid boxing, the corresponding primitive-based methods
* should be used. For example, {@link PrimitiveIterator.OfInt#nextInt()} and
* {@link PrimitiveIterator.OfInt#forEachRemaining(java.util.function.IntConsumer)}
* should be used in preference to {@link PrimitiveIterator.OfInt#next()} and
* {@link PrimitiveIterator.OfInt#forEachRemaining(java.util.function.Consumer)}.
*
* <p>Iteration of primitive values using boxing-based methods
* {@link Iterator#next next()} and
* {@link Iterator#forEachRemaining(java.util.function.Consumer) forEachRemaining()},
* does not affect the order in which the values, transformed to boxed values,
* are encountered.
*
* @implNote
* If the boolean system property {@code org.openjdk.java.util.stream.tripwire}
* is set to {@code true} then diagnostic warnings are reported if boxing of
* primitive values occur when operating on primitive subtype specializations.
*
* @param <T> the boxed type of the primitive type
* @since 1.8
*/
public interface PrimitiveIterator<T> extends Iterator<T> {
/**
* An Iterator specialized for {@code int} values.
* @since 1.8
*/
public static interface OfInt extends PrimitiveIterator<Integer> {
/**
* Returns the next {@code int} element in the iteration.
*
* @return the next {@code int} element in the iteration
* @throws NoSuchElementException if the iteration has no more elements
*/
int nextInt();
/**
* Performs the given action for each remaining element, in the order
* elements occur when iterating, until all elements have been processed
* or the action throws an exception. Errors or runtime exceptions
* thrown by the action are relayed to the caller.
*
* @implSpec
* <p>The default implementation behaves as if:
* <pre>{@code
* while (hasNext())
* action.accept(nextInt());
* }</pre>
*
* @param action The action to be performed for each element
* @throws NullPointerException if the specified action is null
*/
default void forEachRemaining(IntConsumer action) {
while (hasNext())
action.accept(nextInt());
}
/**
* {@inheritDoc}
* @implSpec
* The default implementation boxes the result of calling
* {@link #nextInt()}, and returns that boxed result.
*/
@Override
default Integer next() {
if (Tripwire.ENABLED)
Tripwire.trip(getClass(), "{0} calling PrimitiveIterator.OfInt.nextInt()");
return nextInt();
}
/**
* {@inheritDoc}
* @implSpec
* If the action is an instance of {@code IntConsumer} then it is cast
* to {@code IntConsumer} and passed to {@link #forEachRemaining};
* otherwise the action is adapted to an instance of
* {@code IntConsumer}, by boxing the argument of {@code IntConsumer},
* and then passed to {@link #forEachRemaining}.
*/
@Override
default void forEachRemaining(Consumer<? super Integer> action) {
if (action instanceof IntConsumer) {
forEachRemaining((IntConsumer) action);
}
else {
if (Tripwire.ENABLED)
Tripwire.trip(getClass(), "{0} calling PrimitiveIterator.OfInt.forEachRemainingInt(action::accept)");
forEachRemaining((IntConsumer) action::accept);
}
}
}
/**
* An Iterator specialized for {@code long} values.
* @since 1.8
*/
public static interface OfLong extends PrimitiveIterator<Long> {
/**
* Returns the next {@code long} element in the iteration.
*
* @return the next {@code long} element in the iteration
* @throws NoSuchElementException if the iteration has no more elements
*/
long nextLong();
/**
* Performs the given action for each remaining element, in the order
* elements occur when iterating, until all elements have been processed
* or the action throws an exception. Errors or runtime exceptions
* thrown by the action are relayed to the caller.
*
* @implSpec
* <p>The default implementation behaves as if:
* <pre>{@code
* while (hasNext())
* action.accept(nextLong());
* }</pre>
*
* @param action The action to be performed for each element
* @throws NullPointerException if the specified action is null
*/
default void forEachRemaining(LongConsumer action) {
while (hasNext())
action.accept(nextLong());
}
/**
* {@inheritDoc}
* @implSpec
* The default implementation boxes the result of calling
* {@link #nextLong()}, and returns that boxed result.
*/
@Override
default Long next() {
if (Tripwire.ENABLED)
Tripwire.trip(getClass(), "{0} calling PrimitiveIterator.OfLong.nextLong()");
return nextLong();
}
/**
* {@inheritDoc}
* @implSpec
* If the action is an instance of {@code LongConsumer} then it is cast
* to {@code LongConsumer} and passed to {@link #forEachRemaining};
* otherwise the action is adapted to an instance of
* {@code LongConsumer}, by boxing the argument of {@code LongConsumer},
* and then passed to {@link #forEachRemaining}.
*/
@Override
default void forEachRemaining(Consumer<? super Long> action) {
if (action instanceof LongConsumer) {
forEachRemaining((LongConsumer) action);
}
else {
if (Tripwire.ENABLED)
Tripwire.trip(getClass(), "{0} calling PrimitiveIterator.OfLong.forEachRemainingLong(action::accept)");
forEachRemaining((LongConsumer) action::accept);
}
}
}
/**
* An Iterator specialized for {@code double} values.
* @since 1.8
*/
public static interface OfDouble extends PrimitiveIterator<Double> {
/**
* Returns the next {@code double} element in the iteration.
*
* @return the next {@code double} element in the iteration
* @throws NoSuchElementException if the iteration has no more elements
*/
double nextDouble();
/**
* Performs the given action for each remaining element, in the order
* elements occur when iterating, until all elements have been processed
* or the action throws an exception. Errors or runtime exceptions
* thrown by the action are relayed to the caller.
*
* @implSpec
* <p>The default implementation behaves as if:
* <pre>{@code
* while (hasNext())
* action.accept(nextDouble());
* }</pre>
*
* @param action The action to be performed for each element
* @throws NullPointerException if the specified action is null
*/
default void forEachRemaining(DoubleConsumer action) {
while (hasNext())
action.accept(nextDouble());
}
/**
* {@inheritDoc}
* @implSpec
* The default implementation boxes the result of calling
* {@link #nextDouble()}, and returns that boxed result.
*/
@Override
default Double next() {
if (Tripwire.ENABLED)
Tripwire.trip(getClass(), "{0} calling PrimitiveIterator.OfDouble.nextLong()");
return nextDouble();
}
/**
* {@inheritDoc}
* @implSpec
* If the action is an instance of {@code DoubleConsumer} then it is
* cast to {@code DoubleConsumer} and passed to
* {@link #forEachRemaining}; otherwise the action is adapted to
* an instance of {@code DoubleConsumer}, by boxing the argument of
* {@code DoubleConsumer}, and then passed to
* {@link #forEachRemaining}.
*/
@Override
default void forEachRemaining(Consumer<? super Double> action) {
if (action instanceof DoubleConsumer) {
forEachRemaining((DoubleConsumer) action);
}
else {
if (Tripwire.ENABLED)
Tripwire.trip(getClass(), "{0} calling PrimitiveIterator.OfDouble.forEachRemainingDouble(action::accept)");
forEachRemaining((DoubleConsumer) action::accept);
}
}
}
}
/*
* Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 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
......@@ -382,4 +382,29 @@ public interface Set<E> extends Collection<E> {
* @see Set#equals(Object)
*/
int hashCode();
/**
* Creates a {@code Spliterator} over the elements in this set.
*
* <p>The {@code Spliterator} reports {@link Spliterator#SIZED} and
* {@link Spliterator#DISTINCT}. Implementations should document the
* reporting of additional characteristic values.
*
* @implSpec
* The default implementation creates a
* <em><a href="Spliterator.html#binding">late-binding</a></em> spliterator
* from the set's {@code Iterator}. The spliterator inherits the
* <em>fail-fast</em> properties of the collection's iterator.
*
* @implNote
* The created {@code Spliterator} additionally reports
* {@link Spliterator#SUBSIZED}.
*
* @return a {@code Spliterator} over the elements in this set
* @since 1.8
*/
@Override
default Spliterator<E> spliterator() {
return Spliterators.spliterator(this, Spliterator.DISTINCT);
}
}
/*
* Copyright (c) 1998, 2006, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 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
......@@ -219,4 +219,43 @@ public interface SortedSet<E> extends Set<E> {
* @throws NoSuchElementException if this set is empty
*/
E last();
/**
* Creates a {@code Spliterator} over the elements in this sorted set.
*
* <p>The {@code Spliterator} reports {@link Spliterator#SIZED},
* {@link Spliterator#DISTINCT}, {@link Spliterator#SORTED} and
* {@link Spliterator#ORDERED}. Implementations should document the
* reporting of additional characteristic values.
*
* <p>The spliterator's comparator (see
* {@link java.util.Spliterator#getComparator()}) must be {@code null} if
* the sorted set's comparator (see {@link #comparator()}) is {@code null}.
* Otherwise, the spliterator's comparator must be the same as or impose the
* same total ordering as the sorted set's comparator.
*
* @implSpec
* The default implementation creates a
* <em><a href="Spliterator.html#binding">late-binding</a></em> spliterator
* from the sorted set's {@code Iterator}. The spliterator inherits the
* <em>fail-fast</em> properties of the collection's iterator. The
* spliterator's comparator is the same as the sorted set's comparator.
*
* @implNote
* The created {@code Spliterator} additionally reports
* {@link Spliterator#SUBSIZED}.
*
* @return a {@code Spliterator} over the elements in this sorted set
* @since 1.8
*/
@Override
default Spliterator<E> spliterator() {
return new Spliterators.IteratorSpliterator<E>(
this, Spliterator.DISTINCT | Spliterator.SORTED | Spliterator.ORDERED) {
@Override
public Comparator<? super E> getComparator() {
return SortedSet.this.comparator();
}
};
}
}
此差异已折叠。
此差异已折叠。
/*
* 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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;
import sun.util.logging.PlatformLogger;
import java.security.AccessController;
import java.security.PrivilegedAction;
/**
* Utility class for detecting inadvertent uses of boxing in
* {@code java.util} classes. The detection is turned on or off based on
* whether the system property {@code org.openjdk.java.util.stream.tripwire} is
* considered {@code true} according to {@link Boolean#getBoolean(String)}.
* This should normally be turned off for production use.
*
* @apiNote
* Typical usage would be for boxing code to do:
* <pre>{@code
* if (Tripwire.ENABLED)
* Tripwire.trip(getClass(), "{0} calling PrimitiveIterator.OfInt.nextInt()");
* }</pre>
*
* @since 1.8
*/
final class Tripwire {
private static final String TRIPWIRE_PROPERTY = "org.openjdk.java.util.stream.tripwire";
/** Should debugging checks be enabled? */
static final boolean ENABLED = AccessController.doPrivileged(
(PrivilegedAction<Boolean>) () -> Boolean.getBoolean(TRIPWIRE_PROPERTY));
private Tripwire() { }
/**
* Produces a log warning, using {@code PlatformLogger.getLogger(className)},
* using the supplied message. The class name of {@code trippingClass} will
* be used as the first parameter to the message.
*
* @param trippingClass Name of the class generating the message
* @param msg A message format string of the type expected by
* {@link PlatformLogger}
*/
static void trip(Class<?> trippingClass, String msg) {
PlatformLogger.getLogger(trippingClass.getName()).warning(msg, trippingClass.getName());
}
}
/*
* 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 org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.ConcurrentModificationException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.PriorityQueue;
import java.util.Set;
import java.util.Spliterator;
import java.util.Stack;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.Vector;
import java.util.WeakHashMap;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
import static org.testng.Assert.*;
/**
* @test
* @summary Spliterator last-binding and fail-fast tests
* @run testng SpliteratorLateBindingFailFastTest
*/
@Test
public class SpliteratorLateBindingFailFastTest {
private interface Source<T> {
Collection<T> asCollection();
void update();
}
private static class SpliteratorDataBuilder<T> {
final List<Object[]> data;
final T newValue;
final List<T> exp;
final Map<T, T> mExp;
SpliteratorDataBuilder(List<Object[]> data, T newValue, List<T> exp) {
this.data = data;
this.newValue = newValue;
this.exp = exp;
this.mExp = createMap(exp);
}
Map<T, T> createMap(List<T> l) {
Map<T, T> m = new LinkedHashMap<>();
for (T t : l) {
m.put(t, t);
}
return m;
}
void add(String description, Supplier<Source<?>> s) {
description = joiner(description).toString();
data.add(new Object[]{description, s});
}
void addCollection(Function<Collection<T>, ? extends Collection<T>> f) {
class CollectionSource implements Source<T> {
final Collection<T> c = f.apply(exp);
final Consumer<Collection<T>> updater;
CollectionSource(Consumer<Collection<T>> updater) {
this.updater = updater;
}
@Override
public Collection<T> asCollection() {
return c;
}
@Override
public void update() {
updater.accept(c);
}
}
String description = "new " + f.apply(Collections.<T>emptyList()).getClass().getName() + ".spliterator() ";
add(description + "ADD", () -> new CollectionSource(c -> c.add(newValue)));
add(description + "REMOVE", () -> new CollectionSource(c -> c.remove(c.iterator().next())));
}
void addList(Function<Collection<T>, ? extends List<T>> l) {
// @@@ If collection is instance of List then add sub-list tests
addCollection(l);
}
void addMap(Function<Map<T, T>, ? extends Map<T, T>> mapConstructor) {
class MapSource<U> implements Source<U> {
final Map<T, T> m = mapConstructor.apply(mExp);
final Collection<U> c;
final Consumer<Map<T, T>> updater;
MapSource(Function<Map<T, T>, Collection<U>> f, Consumer<Map<T, T>> updater) {
this.c = f.apply(m);
this.updater = updater;
}
@Override
public Collection<U> asCollection() {
return c;
}
@Override
public void update() {
updater.accept(m);
}
}
Map<String, Consumer<Map<T, T>>> actions = new HashMap<>();
actions.put("ADD", m -> m.put(newValue, newValue));
actions.put("REMOVE", m -> m.remove(m.keySet().iterator().next()));
String description = "new " + mapConstructor.apply(Collections.<T, T>emptyMap()).getClass().getName();
for (Map.Entry<String, Consumer<Map<T, T>>> e : actions.entrySet()) {
add(description + ".keySet().spliterator() " + e.getKey(),
() -> new MapSource<T>(m -> m.keySet(), e.getValue()));
add(description + ".values().spliterator() " + e.getKey(),
() -> new MapSource<T>(m -> m.values(), e.getValue()));
add(description + ".entrySet().spliterator() " + e.getKey(),
() -> new MapSource<Map.Entry<T, T>>(m -> m.entrySet(), e.getValue()));
}
}
StringBuilder joiner(String description) {
return new StringBuilder(description).
append(" {").
append("size=").append(exp.size()).
append("}");
}
}
static Object[][] spliteratorDataProvider;
@DataProvider(name = "Source")
public static Object[][] spliteratorDataProvider() {
if (spliteratorDataProvider != null) {
return spliteratorDataProvider;
}
List<Object[]> data = new ArrayList<>();
SpliteratorDataBuilder<Integer> db = new SpliteratorDataBuilder<>(data, 5, Arrays.asList(1, 2, 3, 4));
// Collections
db.addList(ArrayList::new);
db.addList(LinkedList::new);
db.addList(Vector::new);
db.addCollection(HashSet::new);
db.addCollection(LinkedHashSet::new);
db.addCollection(TreeSet::new);
db.addCollection(c -> { Stack<Integer> s = new Stack<>(); s.addAll(c); return s;});
db.addCollection(PriorityQueue::new);
// ArrayDeque fails some tests since it's fail-fast support is weaker
// than other collections and limited to detecting most, but not all,
// removals. It probably requires it's own test since it is difficult
// to abstract out the conditions under which it fails-fast.
// db.addCollection(ArrayDeque::new);
// Maps
db.addMap(HashMap::new);
db.addMap(LinkedHashMap::new);
// This fails when run through jrteg but passes when run though
// ant
// db.addMap(IdentityHashMap::new);
db.addMap(WeakHashMap::new);
// @@@ Descending maps etc
db.addMap(TreeMap::new);
return spliteratorDataProvider = data.toArray(new Object[0][]);
}
@Test(dataProvider = "Source")
public <T> void lateBindingTestWithForEach(String description, Supplier<Source<T>> ss) {
Source<T> source = ss.get();
Collection<T> c = source.asCollection();
Spliterator<T> s = c.spliterator();
source.update();
Set<T> r = new HashSet<>();
s.forEachRemaining(r::add);
assertEquals(r, new HashSet<>(c));
}
@Test(dataProvider = "Source")
public <T> void lateBindingTestWithTryAdvance(String description, Supplier<Source<T>> ss) {
Source<T> source = ss.get();
Collection<T> c = source.asCollection();
Spliterator<T> s = c.spliterator();
source.update();
Set<T> r = new HashSet<>();
while (s.tryAdvance(r::add)) { }
assertEquals(r, new HashSet<>(c));
}
@Test(dataProvider = "Source")
public <T> void lateBindingTestWithCharacteritics(String description, Supplier<Source<T>> ss) {
Source<T> source = ss.get();
Collection<T> c = source.asCollection();
Spliterator<T> s = c.spliterator();
s.characteristics();
Set<T> r = new HashSet<>();
s.forEachRemaining(r::add);
assertEquals(r, new HashSet<>(c));
}
@Test(dataProvider = "Source")
public <T> void testFailFastTestWithTryAdvance(String description, Supplier<Source<T>> ss) {
{
Source<T> source = ss.get();
Collection<T> c = source.asCollection();
Spliterator<T> s = c.spliterator();
s.tryAdvance(e -> {
});
source.update();
executeAndCatch(() -> s.tryAdvance(e -> { }));
}
{
Source<T> source = ss.get();
Collection<T> c = source.asCollection();
Spliterator<T> s = c.spliterator();
s.tryAdvance(e -> {
});
source.update();
executeAndCatch(() -> s.forEachRemaining(e -> {
}));
}
}
@Test(dataProvider = "Source")
public <T> void testFailFastTestWithForEach(String description, Supplier<Source<T>> ss) {
Source<T> source = ss.get();
Collection<T> c = source.asCollection();
Spliterator<T> s = c.spliterator();
executeAndCatch(() -> s.forEachRemaining(e -> {
source.update();
}));
}
@Test(dataProvider = "Source")
public <T> void testFailFastTestWithEstimateSize(String description, Supplier<Source<T>> ss) {
{
Source<T> source = ss.get();
Collection<T> c = source.asCollection();
Spliterator<T> s = c.spliterator();
s.estimateSize();
source.update();
executeAndCatch(() -> s.tryAdvance(e -> { }));
}
{
Source<T> source = ss.get();
Collection<T> c = source.asCollection();
Spliterator<T> s = c.spliterator();
s.estimateSize();
source.update();
executeAndCatch(() -> s.forEachRemaining(e -> {
}));
}
}
private void executeAndCatch(Runnable r) {
executeAndCatch(ConcurrentModificationException.class, r);
}
private void executeAndCatch(Class<? extends Exception> expected, Runnable r) {
Exception caught = null;
try {
r.run();
}
catch (Exception e) {
caught = e;
}
assertNotNull(caught,
String.format("No Exception was thrown, expected an Exception of %s to be thrown",
expected.getName()));
assertTrue(expected.isInstance(caught),
String.format("Exception thrown %s not an instance of %s",
caught.getClass().getName(), expected.getName()));
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册