/** Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.*********************/package java.util.stream;import java.util.Spliterator;import java.util.function.Consumer;import java.util.function.DoubleConsumer;import java.util.function.IntConsumer;import java.util.function.IntFunction;import java.util.function.LongConsumer;/*** An immutable container for describing an ordered sequence of elements of some* type {@code T}.** <p>A {@code Node} contains a fixed number of elements, which can be accessed* via the {@link #count}, {@link #spliterator}, {@link #forEach},* {@link #asArray}, or {@link #copyInto} methods. A {@code Node} may have zero* or more child {@code Node}s; if it has no children (accessed via* {@link #getChildCount} and {@link #getChild(int)}, it is considered <em>flat* </em> or a <em>leaf</em>; if it has children, it is considered an* <em>internal</em> node. The size of an internal node is the sum of sizes of* its children.** @apiNote* <p>A {@code Node} typically does not store the elements directly, but instead* mediates access to one or more existing (effectively immutable) data* structures such as a {@code Collection}, array, or a set of other* {@code Node}s. Commonly {@code Node}s are formed into a tree whose shape* corresponds to the computation tree that produced the elements that are* contained in the leaf nodes. The use of {@code Node} within the stream* framework is largely to avoid copying data unnecessarily during parallel* operations.** @param <T> the type of elements.* @since 1.8*/interface Node<T> {/*** Returns a {@link Spliterator} describing the elements contained in this* {@code Node}.** @return a {@code Spliterator} describing the elements contained in this* {@code Node}*/Spliterator<T> spliterator();/*** Traverses the elements of this node, and invoke the provided* {@code Consumer} with each element. Elements are provided in encounter* order if the source for the {@code Node} has a defined encounter order.** @param consumer a {@code Consumer} that is to be invoked with each* element in this {@code Node}*/void forEach(Consumer<? super T> consumer);/*** Returns the number of child nodes of this node.** @implSpec The default implementation returns zero.** @return the number of child nodes*/default int getChildCount() {return 0;}/*** Retrieves the child {@code Node} at a given index.** @implSpec The default implementation always throws* {@code IndexOutOfBoundsException}.** @param i the index to the child node* @return the child node* @throws IndexOutOfBoundsException if the index is less than 0 or greater* than or equal to the number of child nodes*/default Node<T> getChild(int i) {throw new IndexOutOfBoundsException();}/*** Return a node describing a subsequence of the elements of this node,* starting at the given inclusive start offset and ending at the given* exclusive end offset.** @param from The (inclusive) starting offset of elements to include, must* be in range 0..count().* @param to The (exclusive) end offset of elements to include, must be* in range 0..count().* @param generator A function to be used to create a new array, if needed,* for reference nodes.* @return the truncated node*/default Node<T> truncate(long from, long to, IntFunction<T[]> generator) {if (from == 0 && to == count())return this;Spliterator<T> spliterator = spliterator();long size = to - from;Node.Builder<T> nodeBuilder = Nodes.builder(size, generator);nodeBuilder.begin(size);for (int i = 0; i < from && spliterator.tryAdvance(e -> { }); i++) { }if (to == count()) {spliterator.forEachRemaining(nodeBuilder);} else {for (int i = 0; i < size && spliterator.tryAdvance(nodeBuilder); i++) { }}nodeBuilder.end();return nodeBuilder.build();}/*** Provides an array view of the contents of this node.** <p>Depending on the underlying implementation, this may return a* reference to an internal array rather than a copy. Since the returned* array may be shared, the returned array should not be modified. The* {@code generator} function may be consulted to create the array if a new* array needs to be created.** @param generator a factory function which takes an integer parameter and* returns a new, empty array of that size and of the appropriate* array type* @return an array containing the contents of this {@code Node}*/T[] asArray(IntFunction<T[]> generator);/*** Copies the content of this {@code Node} into an array, starting at a* given offset into the array. It is the caller's responsibility to ensure* there is sufficient room in the array, otherwise unspecified behaviour* will occur if the array length is less than the number of elements* contained in this node.** @param array the array into which to copy the contents of this* {@code Node}* @param offset the starting offset within the array* @throws IndexOutOfBoundsException if copying would cause access of data* outside array bounds* @throws NullPointerException if {@code array} is {@code null}*/void copyInto(T[] array, int offset);/*** Gets the {@code StreamShape} associated with this {@code Node}.** @implSpec The default in {@code Node} returns* {@code StreamShape.REFERENCE}** @return the stream shape associated with this node*/default StreamShape getShape() {return StreamShape.REFERENCE;}/*** Returns the number of elements contained in this node.** @return the number of elements contained in this node*/long count();/*** A mutable builder for a {@code Node} that implements {@link Sink}, which* builds a flat node containing the elements that have been pushed to it.*/interface Builder<T> extends Sink<T> {/*** Builds the node. Should be called after all elements have been* pushed and signalled with an invocation of {@link Sink#end()}.** @return the resulting {@code Node}*/Node<T> build();/*** Specialized @{code Node.Builder} for int elements*/interface OfInt extends Node.Builder<Integer>, Sink.OfInt {@OverrideNode.OfInt build();}/*** Specialized @{code Node.Builder} for long elements*/interface OfLong extends Node.Builder<Long>, Sink.OfLong {@OverrideNode.OfLong build();}/*** Specialized @{code Node.Builder} for double elements*/interface OfDouble extends Node.Builder<Double>, Sink.OfDouble {@OverrideNode.OfDouble build();}}public interface OfPrimitive<T, T_CONS, T_ARR,T_SPLITR extends Spliterator.OfPrimitive<T, T_CONS, T_SPLITR>,T_NODE extends OfPrimitive<T, T_CONS, T_ARR, T_SPLITR, T_NODE>>extends Node<T> {/*** {@inheritDoc}** @return a {@link Spliterator.OfPrimitive} describing the elements of* this node*/@OverrideT_SPLITR spliterator();/*** Traverses the elements of this node, and invoke the provided* {@code action} with each element.** @param action a consumer that is to be invoked with each* element in this {@code Node.OfPrimitive}*/@SuppressWarnings("overloads")void forEach(T_CONS action);@Overridedefault T_NODE getChild(int i) {throw new IndexOutOfBoundsException();}T_NODE truncate(long from, long to, IntFunction<T[]> generator);/*** {@inheritDoc}** @implSpec the default implementation invokes the generator to create* an instance of a boxed primitive array with a length of* {@link #count()} and then invokes {@link #copyInto(T[], int)} with* that array at an offset of 0.*/@Overridedefault T[] asArray(IntFunction<T[]> generator) {if (java.util.stream.Tripwire.ENABLED)java.util.stream.Tripwire.trip(getClass(), "{0} calling Node.OfPrimitive.asArray");long size = count();if (size >= Nodes.MAX_ARRAY_SIZE)throw new IllegalArgumentException(Nodes.BAD_SIZE);T[] boxed = generator.apply((int) count());copyInto(boxed, 0);return boxed;}/*** Views this node as a primitive array.** <p>Depending on the underlying implementation this may return a* reference to an internal array rather than a copy. It is the callers* responsibility to decide if either this node or the array is utilized* as the primary reference for the data.</p>** @return an array containing the contents of this {@code Node}*/T_ARR asPrimitiveArray();/*** Creates a new primitive array.** @param count the length of the primitive array.* @return the new primitive array.*/T_ARR newArray(int count);/*** Copies the content of this {@code Node} into a primitive array,* starting at a given offset into the array. It is the caller's* responsibility to ensure there is sufficient room in the array.** @param array the array into which to copy the contents of this* {@code Node}* @param offset the starting offset within the array* @throws IndexOutOfBoundsException if copying would cause access of* data outside array bounds* @throws NullPointerException if {@code array} is {@code null}*/void copyInto(T_ARR array, int offset);}/*** Specialized {@code Node} for int elements*/interface OfInt extends OfPrimitive<Integer, IntConsumer, int[], Spliterator.OfInt, OfInt> {/*** {@inheritDoc}** @param consumer a {@code Consumer} that is to be invoked with each* element in this {@code Node}. If this is an* {@code IntConsumer}, it is cast to {@code IntConsumer} so the* elements may be processed without boxing.*/@Overridedefault void forEach(Consumer<? super Integer> consumer) {if (consumer instanceof IntConsumer) {forEach((IntConsumer) consumer);}else {if (Tripwire.ENABLED)Tripwire.trip(getClass(), "{0} calling Node.OfInt.forEachRemaining(Consumer)");spliterator().forEachRemaining(consumer);}}/*** {@inheritDoc}** @implSpec the default implementation invokes {@link #asPrimitiveArray()} to* obtain an int[] array then and copies the elements from that int[]* array into the boxed Integer[] array. This is not efficient and it* is recommended to invoke {@link #copyInto(Object, int)}.*/@Overridedefault void copyInto(Integer[] boxed, int offset) {if (Tripwire.ENABLED)Tripwire.trip(getClass(), "{0} calling Node.OfInt.copyInto(Integer[], int)");int[] array = asPrimitiveArray();for (int i = 0; i < array.length; i++) {boxed[offset + i] = array[i];}}@Overridedefault Node.OfInt truncate(long from, long to, IntFunction<Integer[]> generator) {if (from == 0 && to == count())return this;long size = to - from;Spliterator.OfInt spliterator = spliterator();Node.Builder.OfInt nodeBuilder = Nodes.intBuilder(size);nodeBuilder.begin(size);for (int i = 0; i < from && spliterator.tryAdvance((IntConsumer) e -> { }); i++) { }if (to == count()) {spliterator.forEachRemaining((IntConsumer) nodeBuilder);} else {for (int i = 0; i < size && spliterator.tryAdvance((IntConsumer) nodeBuilder); i++) { }}nodeBuilder.end();return nodeBuilder.build();}@Overridedefault int[] newArray(int count) {return new int[count];}/*** {@inheritDoc}* @implSpec The default in {@code Node.OfInt} returns* {@code StreamShape.INT_VALUE}*/default StreamShape getShape() {return StreamShape.INT_VALUE;}}/*** Specialized {@code Node} for long elements*/interface OfLong extends OfPrimitive<Long, LongConsumer, long[], Spliterator.OfLong, OfLong> {/*** {@inheritDoc}** @param consumer A {@code Consumer} that is to be invoked with each* element in this {@code Node}. If this is an* {@code LongConsumer}, it is cast to {@code LongConsumer} so* the elements may be processed without boxing.*/@Overridedefault void forEach(Consumer<? super Long> consumer) {if (consumer instanceof LongConsumer) {forEach((LongConsumer) consumer);}else {if (Tripwire.ENABLED)Tripwire.trip(getClass(), "{0} calling Node.OfLong.forEachRemaining(Consumer)");spliterator().forEachRemaining(consumer);}}/*** {@inheritDoc}** @implSpec the default implementation invokes {@link #asPrimitiveArray()}* to obtain a long[] array then and copies the elements from that* long[] array into the boxed Long[] array. This is not efficient and* it is recommended to invoke {@link #copyInto(Object, int)}.*/@Overridedefault void copyInto(Long[] boxed, int offset) {if (Tripwire.ENABLED)Tripwire.trip(getClass(), "{0} calling Node.OfInt.copyInto(Long[], int)");long[] array = asPrimitiveArray();for (int i = 0; i < array.length; i++) {boxed[offset + i] = array[i];}}@Overridedefault Node.OfLong truncate(long from, long to, IntFunction<Long[]> generator) {if (from == 0 && to == count())return this;long size = to - from;Spliterator.OfLong spliterator = spliterator();Node.Builder.OfLong nodeBuilder = Nodes.longBuilder(size);nodeBuilder.begin(size);for (int i = 0; i < from && spliterator.tryAdvance((LongConsumer) e -> { }); i++) { }if (to == count()) {spliterator.forEachRemaining((LongConsumer) nodeBuilder);} else {for (int i = 0; i < size && spliterator.tryAdvance((LongConsumer) nodeBuilder); i++) { }}nodeBuilder.end();return nodeBuilder.build();}@Overridedefault long[] newArray(int count) {return new long[count];}/*** {@inheritDoc}* @implSpec The default in {@code Node.OfLong} returns* {@code StreamShape.LONG_VALUE}*/default StreamShape getShape() {return StreamShape.LONG_VALUE;}}/*** Specialized {@code Node} for double elements*/interface OfDouble extends OfPrimitive<Double, DoubleConsumer, double[], Spliterator.OfDouble, OfDouble> {/*** {@inheritDoc}** @param consumer A {@code Consumer} that is to be invoked with each* element in this {@code Node}. If this is an* {@code DoubleConsumer}, it is cast to {@code DoubleConsumer}* so the elements may be processed without boxing.*/@Overridedefault void forEach(Consumer<? super Double> consumer) {if (consumer instanceof DoubleConsumer) {forEach((DoubleConsumer) consumer);}else {if (Tripwire.ENABLED)Tripwire.trip(getClass(), "{0} calling Node.OfLong.forEachRemaining(Consumer)");spliterator().forEachRemaining(consumer);}}///*** {@inheritDoc}** @implSpec the default implementation invokes {@link #asPrimitiveArray()}* to obtain a double[] array then and copies the elements from that* double[] array into the boxed Double[] array. This is not efficient* and it is recommended to invoke {@link #copyInto(Object, int)}.*/@Overridedefault void copyInto(Double[] boxed, int offset) {if (Tripwire.ENABLED)Tripwire.trip(getClass(), "{0} calling Node.OfDouble.copyInto(Double[], int)");double[] array = asPrimitiveArray();for (int i = 0; i < array.length; i++) {boxed[offset + i] = array[i];}}@Overridedefault Node.OfDouble truncate(long from, long to, IntFunction<Double[]> generator) {if (from == 0 && to == count())return this;long size = to - from;Spliterator.OfDouble spliterator = spliterator();Node.Builder.OfDouble nodeBuilder = Nodes.doubleBuilder(size);nodeBuilder.begin(size);for (int i = 0; i < from && spliterator.tryAdvance((DoubleConsumer) e -> { }); i++) { }if (to == count()) {spliterator.forEachRemaining((DoubleConsumer) nodeBuilder);} else {for (int i = 0; i < size && spliterator.tryAdvance((DoubleConsumer) nodeBuilder); i++) { }}nodeBuilder.end();return nodeBuilder.build();}@Overridedefault double[] newArray(int count) {return new double[count];}/*** {@inheritDoc}** @implSpec The default in {@code Node.OfDouble} returns* {@code StreamShape.DOUBLE_VALUE}*/default StreamShape getShape() {return StreamShape.DOUBLE_VALUE;}}}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。