博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Stream流与Lambda表达式(六) SpliteratorDetail
阅读量:6223 次
发布时间:2019-06-21

本文共 33101 字,大约阅读时间需要 110 分钟。

package com.java.design.java8.Stream.StreamDetail.BaseStreamDetail;import org.junit.Before;import org.junit.Test;import org.junit.runner.RunWith;import org.springframework.boot.test.context.SpringBootTest;import org.springframework.test.context.junit4.SpringRunner;import java.util.Arrays;import java.util.List;import java.util.function.Consumer;import java.util.function.IntConsumer;/** * @author 陈杨 */@SpringBootTest@RunWith(SpringRunner.class)public class SpliteratorDetail {    private IntConsumer intConsumer;    private Consumer consumer;    private List
list; @Before public void init() { intConsumer = System.out::println; consumer = System.out::println; list = Arrays.asList("Kirito", "Asuna", "Sinon", "Yuuki", "Alice"); } private void action(IntConsumer intConsumer) { intConsumer.accept(100); } @Test public void testSpliteratorDetail() {

一、流的创建--源(集合)

// 一、流的创建--源(集合)/*Collection集合默认方法 list.stream()defaultStream
stream () { return StreamSupport.stream(spliterator(), false);}@OverridedefaultSpliterator
spliterator () { return Spliterators.spliterator(this, 0);}public static
Spliterator
spliterator(Collection
c,int characteristics) { return new IteratorSpliterator<>(Objects.requireNonNull(c), characteristics);}*/// Collector 接口 与 Collectors 静态类实现// Spliterator 接口 与 Spliterators 静态类实现

二、Spliterator 接口

//  二、Spliterator 接口//  Spliterator 接口//  对数据源中元素进行遍历或分区//  An object for traversing and partitioning elements of a source.
//  延迟绑定数据源//      绑定时机:首次遍历、切分、查询大小 而不是在创建时//  A  late-binding Spliterator binds to the source of elements at the//  point of first traversal, first split, or first query for estimated size,//  rather than at the time the Spliterator is created.//  非延迟绑定数据源//      绑定时机:Spliterator创建时 或Spliterator的方法首次调用//  A Spliterator that is not late-binding binds to the source of elements//  at the point of construction or first invocation of any method.
//  Spliterator 与 Iterator 的区别:////  Spliterator 优势:通过分解和单元素迭代 支持串行与并行//                    比Iterator迭代通过hasNext与next性能更好//  Spliterators, like {@code Iterator}s, are for traversing the elements of  a source.//  The Spliterator API was designed to support efficient parallel traversal//  in addition to sequential traversal, by supporting decomposition as well as single-element iteration.//  In addition, the protocol for accessing elements via a Spliterator is designed to impose//  smaller per-element overhead than {@code Iterator}, and to avoid the inherent//  race involved in having separate methods for {@code hasNext()} and {@code next()}.

三、Spliterator特性值

/* public interface Spliterator
{// 三、Spliterator特性值 * Characteristic value signifying that an encounter order is defined for * elements. If so, this Spliterator guarantees that method * {@link #trySplit} splits a strict prefix of elements, that method 分割前后对元素加严格前缀 * {@link #tryAdvance} steps by one element in prefix order, and that 按照元素的顺序前缀遍历 * {@link #forEachRemaining} performs actions in encounter order. 对剩余元素按照相遇顺序执行action * *

A {@link Collection} has an encounter order if the corresponding * {@link Collection#iterator} documents an order. If so, the encounter * order is the same as the documented order. Otherwise, a collection does * not have an encounter order. * 集合是有序的,则文档是有序的 * 集合是无序的,则文档是无序的 * * @apiNote Encounter order is guaranteed to be ascending index order for * any {@link List}. But no order is guaranteed for hash-based collections * such as {@link HashSet}. Clients of a Spliterator that reports * {@code ORDERED} are expected to preserve ordering constraints in * non-commutative parallel computations. * 基于索引升序的List 排序-->有序 * 基于Hash散列的HashSet 排序-->无序 * 非并发情况下期望要保留 有序集合中 元素的顺序 以返还给客户端调用者 public static final int ORDERED = 0x00000010; * Characteristic value signifying that, for each pair of * encountered elements {@code x, y}, {@code !x.equals(y)}. This * applies for example, to a Spliterator based on a {@link Set}. 基于Set的去重DISTINCT public static final int DISTINCT = 0x00000001; * Characteristic value signifying that encounter order follows a defined * sort order. If so, method {@link #getComparator()} returns the associated * Comparator, or {@code null} if all elements are {@link Comparable} and * are sorted by their natural ordering. * *

A Spliterator that reports {@code SORTED} must also report * {@code ORDERED}. * 已排序的一定是有序的 * * @apiNote The spliterators for {@code Collection} classes in the JDK that * implement {@link NavigableSet} or {@link SortedSet} report {@code SORTED}. * 如果基于集合的spliterator实现了NavigableSet或SortedSet接口 则为SORTED public static final int SORTED = 0x00000004; * Characteristic value signifying that the value returned from * {@code estimateSize()} prior to traversal or splitting represents a * finite size that, in the absence of structural source modification, * represents an exact count of the number of elements that would be * encountered by a complete traversal. * 源中元素个数有限 源元素结构特性未被修改 estimateSize能在完整遍历过程中 精准计算 public static final int SIZED = 0x00000040; * Characteristic value signifying that the source guarantees that * encountered elements will not be {@code null}. (This applies, * for example, to most concurrent collections, queues, and maps.) * 源中元素都不为null public static final int NONNULL = 0x00000100; * Characteristic value signifying that the element source cannot be * structurally modified; that is, elements cannot be added, replaced, or * removed, so such changes cannot occur during traversal. A Spliterator * that does not report {@code IMMUTABLE} or {@code CONCURRENT} is expected * to have a documented policy (for example throwing * {@link ConcurrentModificationException}) concerning structural * interference detected during traversal. * 源中元素结构不可变 * 源中元素在遍历过程中 不能被 添加 替换(包含修改) 删除 * 如果遍历时 发送元素结构发生改变 则不能表示为IMMUTABLE或CONCURRENT 抛出ConcurrentModificationException public static final int IMMUTABLE = 0x00000400; * Characteristic value signifying that the element source may be safely * concurrently modified (allowing additions, replacements, and/or removals) * by multiple threads without external synchronization. If so, the * Spliterator is expected to have a documented policy concerning the impact * of modifications during traversal. * *

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 * that Spliterator. Sub-spliterators may report {@code SIZED} if the * sub-split size is known and additions or removals to the source are not * reflected when traversing. * *

A top-level Spliterator should not report both {@code CONCURRENT} and * {@code IMMUTABLE}, since they are mutually exclusive. Such a Spliterator * is inconsistent and no guarantees can be made about any computation using * that Spliterator. Sub-spliterators may report {@code IMMUTABLE} if * additions or removals to the source are not reflected when traversing. * * @apiNote Most concurrent collections maintain a consistency policy * guaranteeing accuracy with respect to elements present at the point of * Spliterator construction, but possibly not reflecting subsequent * additions or removals. * 顶层的Spliterator不能同时拥有CONCURRENT和SIZED特性 * 并发时可能存在对源进行添加、替换(修改)、删除 以改变元素个数 * 顶层的Spliterator不能同时拥有CONCURRENT和IMMUTABLE特性 * 这两种特性是互斥的 * 大多数并发集合都保持一致性策略,以确保在拆分器构造点存在的元素的准确性,但可能不反映随后的添加或删除 public static final int CONCURRENT = 0x00001000; * Characteristic value signifying that all Spliterators resulting from * {@code trySplit()} will be both {@link #SIZED} and {@link #SUBSIZED}. * (This means that all child Spliterators, whether direct or indirect, will * be {@code SIZED}.) * *

A Spliterator that does not report {@code SIZED} as required by * {@code SUBSIZED} is inconsistent and no guarantees can be made about any * computation using that Spliterator. * * @apiNote Some spliterators, such as the top-level spliterator for an * approximately balanced binary tree, will report {@code SIZED} but not * {@code SUBSIZED}, since it is common to know the size of the entire tree * but not the exact sizes of subtrees. * 顶层二叉树是SIZED 但不是SUBSIZED 因为不知道子树的大小 * 从trySplit返回的子Spliterator都是SIZED 和 SUBSIZED public static final int SUBSIZED = 0x00004000;

四、Spliterator方法

//  四、Spliterator方法     * If a remaining element exists, performs the given action on it,     * returning {@code true}; else returns {@code false}.  If this     * Spliterator is {@link #ORDERED} the action is performed on the     * next element in encounter order.  Exceptions thrown by the     * action are relayed to the caller.     *    尝试遍历:        如果有下一个元素 就对其执行action        如果是有序的 按照元素相遇顺序 对其执行action        如果有异常 将异常信息返回给方法调用者        tryAdvance() 完成了 Iterator的hasNext()与next()    boolean tryAdvance(Consumer
action); * Performs the given action for each remaining element, sequentially in * the current thread, until all elements have been processed or the action * throws an exception. If this Spliterator is {@link #ORDERED}, actions * are performed in encounter order. Exceptions thrown by the action * are relayed to the caller. 按顺序遍历剩余元素 并对每个元素执行action 直到遍历结束 将异常信息返回给方法调用者 default void forEachRemaining(Consumer
action) { do { } while (tryAdvance(action)); } * If this spliterator can be partitioned, returns a Spliterator * covering elements, that will, upon return from this method, not * be covered by this Spliterator. * *

If this Spliterator is {@link #ORDERED}, the returned Spliterator * must cover a strict prefix of the elements. * *

Unless this Spliterator covers an infinite number of elements, * repeated calls to {@code trySplit()} must eventually return {@code null}. * Upon non-null return: *

    *
  • the value reported for {@code estimateSize()} before splitting, * must, after splitting, be greater than or equal to {@code estimateSize()} * for this and the returned Spliterator; and
  • *
  • if this Spliterator is {@code SUBSIZED}, then {@code estimateSize()} * for this spliterator before splitting must be equal to the sum of * {@code estimateSize()} for this and the returned Spliterator after * splitting.
  • *
* *

This method may return {@code null} for any reason, * including emptiness, inability to split after traversal has * commenced, data structure constraints, and efficiency * considerations. * * @apiNote * An ideal {@code trySplit} method efficiently (without * traversal) divides its elements exactly in half, allowing * balanced parallel computation. Many departures from this ideal * remain highly effective; for example, only approximately * splitting an approximately balanced tree, or for a tree in * which leaf nodes may contain either one or two elements, * failing to further split these nodes. However, large * deviations in balance and/or overly inefficient {@code * trySplit} mechanics typically result in poor parallel * performance. 尝试对Spliterator中元素进行trySplit 若能进行拆分,则返回一个新的Spliterator对象 装载已分割的元素 如果分割前有序,分割后也是有序的 分割结果不为null: 进行有限分割后 最终能得到非null元素 分割结果为null: 对有限元素个数的分割:进行无限分割 分割前元素个数为null 遍历开始后无法拆分 数据结构约束 性能考量 Spliterator

trySplit(); * Returns an estimate of the number of elements that would be * encountered by a {@link #forEachRemaining} traversal, or returns {@link * Long#MAX_VALUE} if infinite, unknown, or too expensive to compute. * *

If this Spliterator is {@link #SIZED} and has not yet been partially * traversed or split, or this Spliterator is {@link #SUBSIZED} and has * not yet been partially traversed, this estimate must be an accurate * count of elements that would be encountered by a complete traversal. * Otherwise, this estimate may be arbitrarily inaccurate, but must decrease * as specified across invocations of {@link #trySplit}. * * @apiNote * Even an inexact estimate is often useful and inexpensive to compute. * For example, a sub-spliterator of an approximately balanced binary tree * may return a value that estimates the number of elements to be half of * that of its parent; if the root Spliterator does not maintain an * accurate count, it could estimate size to be the power of two * corresponding to its maximum depth. 估算元素数量(即将遍历的元素个数) 如果元素数量无限 未知 或计算成本很昂贵 返回Long.Max_Value 如果Spliterator是一个SIZED或SUBSIZED estimate则是完整遍历所需要的值(accurate精确) long estimateSize(); * Convenience method that returns {@link #estimateSize()} if this * Spliterator is {@link #SIZED}, else {@code -1}. characteristic.SIZED -->返回确定的大小 否则为 -1L default long getExactSizeIfKnown() { return (characteristics() & SIZED) == 0 ? -1L : estimateSize(); } * Returns a set of characteristics of this Spliterator and its * elements. The result is represented as ORed values from {@link * #ORDERED}, {@link #DISTINCT}, {@link #SORTED}, {@link #SIZED}, * {@link #NONNULL}, {@link #IMMUTABLE}, {@link #CONCURRENT}, * {@link #SUBSIZED}. Repeated calls to {@code characteristics()} on * a given spliterator, prior to or in-between calls to {@code trySplit}, * should always return the same result. * *

If a Spliterator reports an inconsistent set of * characteristics (either those returned from a single invocation * or across multiple invocations), no guarantees can be made * about any computation using this Spliterator. * * @apiNote The characteristics of a given spliterator before splitting * may differ from the characteristics after splitting. For specific * examples see the characteristic values {@link #SIZED}, {@link #SUBSIZED} * and {@link #CONCURRENT}. * * @return a representation of characteristics 返回Spliterator与其元素的一个特性值标识 在分割期间或之前 其元素的特性不变 分割前后若元素的特性发生了变更 对其进行计算行为是不能受到保证的 int characteristics(); * Returns {@code true} if this Spliterator's {@link * #characteristics} contain all of the given characteristics. 判断是否包含此元素特性 default boolean hasCharacteristics(int characteristics) { return (characteristics() & characteristics) == characteristics; } * If this Spliterator's source is {@link #SORTED} by a {@link Comparator}, * returns that {@code Comparator}. If the source is {@code SORTED} in * {@linkplain Comparable natural order}, returns {@code null}. Otherwise, * if the source is not {@code SORTED}, throws {@link IllegalStateException}. 如果source是有序的: 如果是按照比较器进行排序 则返回该比较器 如果是Comparable natural order 则返回null 如果source是无序的 抛出IllegalStateException异常 default Comparator

getComparator() { throw new IllegalStateException(); } * A Spliterator specialized for primitive values. * 针对于原生类型值的特化分割器 * * @param
the type of elements returned by this Spliterator. * The type must be a wrapper type for a primitive type, * such as {@code Integer} for the primitive {@code int} type. * @param
the type of primitive consumer. The type must be a * primitive specialization of {@link java.util.function.Consumer} for * {@code T}, such as {@link java.util.function.IntConsumer} for {@code Integer}. * @param
the type of primitive Spliterator. The type must be * a primitive specialization of Spliterator for {@code T}, such as * {@link Spliterator.OfInt} for {@code Integer}. * * @see Spliterator.OfInt * @see Spliterator.OfLong * @see Spliterator.OfDouble * @since 1.8 * T Spliterator返回的元素类型:原生包装类型 * T_CONS primitive consumer :java.util.function.IntConsumer对Integer的原生特化 * T_SPLITR primitive Spliterator :Spliterator.OfInt对Integer的原生特化 * public interface OfPrimitive
> extends Spliterator
{ @Override T_SPLITR trySplit(); @SuppressWarnings("overloads") boolean tryAdvance(T_CONS action); @SuppressWarnings("overloads") default void forEachRemaining(T_CONS action) { do { } while (tryAdvance(action)); } } * A Spliterator specialized for {@code int} values. * @since 1.8 public interface OfInt extends OfPrimitive
{ @Override OfInt trySplit(); @Override boolean tryAdvance(IntConsumer action); @Override default void forEachRemaining(IntConsumer action) { do { } while (tryAdvance(action)); }

五、Consumer 与 IntConsumer、LongConsumer、DoubleConsumer

五、Consumer 与 IntConsumer、LongConsumer、DoubleConsumer        // Consumer 与 IntConsumer 为什么能进行强制类型转换?        // Consumer 与 IntConsumer 之间没有继承关系 层次上无关系        // Consumer 与 IntConsumer 当传入的参数是整型int,Integer时 会自动进行装箱拆箱        // ((IntConsumer) action::accept) 是Lambda表达式        // Lambda表达式 是一种匿名函数 没有方法声明 具有上下文自动推测类型功能         * {@inheritDoc}         * @implSpec         * If the action is an instance of {@code IntConsumer} then it is cast         * to {@code IntConsumer} and passed to         * {@link #tryAdvance(java.util.function.IntConsumer)}; otherwise         * the action is adapted to an instance of {@code IntConsumer}, by         * boxing the argument of {@code IntConsumer}, and then passed to         * {@link #tryAdvance(java.util.function.IntConsumer)}.        @Override        default boolean tryAdvance(Consumer
action) { if (action instanceof IntConsumer) { return tryAdvance((IntConsumer) action); } else { if (Tripwire.ENABLED) Tripwire.trip(getClass(), "{0} calling Spliterator.OfInt.tryAdvance((IntConsumer) action::accept)"); return tryAdvance((IntConsumer) action::accept); } } * {@inheritDoc} * @implSpec * If the action is an instance of {@code IntConsumer} then it is cast * to {@code IntConsumer} and passed to * {@link #forEachRemaining(java.util.function.IntConsumer)}; otherwise * the action is adapted to an instance of {@code IntConsumer}, by * boxing the argument of {@code IntConsumer}, and then passed to * {@link #forEachRemaining(java.util.function.IntConsumer)}. @Override default void forEachRemaining(Consumer
action) { if (action instanceof IntConsumer) { forEachRemaining((IntConsumer) action); } else { if (Tripwire.ENABLED) Tripwire.trip(getClass(), "{0} calling Spliterator.OfInt.forEachRemaining((IntConsumer) action::accept)"); forEachRemaining((IntConsumer) action::accept); } } } * A Spliterator specialized for {@code long} values. * @since 1.8 public interface OfLong extends OfPrimitive
{ @Override OfLong trySplit(); @Override boolean tryAdvance(LongConsumer action); @Override default void forEachRemaining(LongConsumer action) { do { } while (tryAdvance(action)); } * {@inheritDoc} * @implSpec * If the action is an instance of {@code LongConsumer} then it is cast * to {@code LongConsumer} and passed to * {@link #tryAdvance(java.util.function.LongConsumer)}; otherwise * the action is adapted to an instance of {@code LongConsumer}, by * boxing the argument of {@code LongConsumer}, and then passed to * {@link #tryAdvance(java.util.function.LongConsumer)}. @Override default boolean tryAdvance(Consumer
action) { if (action instanceof LongConsumer) { return tryAdvance((LongConsumer) action); } else { if (Tripwire.ENABLED) Tripwire.trip(getClass(), "{0} calling Spliterator.OfLong.tryAdvance((LongConsumer) action::accept)"); return tryAdvance((LongConsumer) action::accept); } } * {@inheritDoc} * @implSpec * If the action is an instance of {@code LongConsumer} then it is cast * to {@code LongConsumer} and passed to * {@link #forEachRemaining(java.util.function.LongConsumer)}; otherwise * the action is adapted to an instance of {@code LongConsumer}, by * boxing the argument of {@code LongConsumer}, and then passed to * {@link #forEachRemaining(java.util.function.LongConsumer)}. @Override default void forEachRemaining(Consumer
action) { if (action instanceof LongConsumer) { forEachRemaining((LongConsumer) action); } else { if (Tripwire.ENABLED) Tripwire.trip(getClass(), "{0} calling Spliterator.OfLong.forEachRemaining((LongConsumer) action::accept)"); forEachRemaining((LongConsumer) action::accept); } } } * A Spliterator specialized for {@code double} values. * @since 1.8 public interface OfDouble extends OfPrimitive
{ @Override OfDouble trySplit(); @Override boolean tryAdvance(DoubleConsumer action); @Override default void forEachRemaining(DoubleConsumer action) { do { } while (tryAdvance(action)); } * {@inheritDoc} * @implSpec * If the action is an instance of {@code DoubleConsumer} then it is * cast to {@code DoubleConsumer} and passed to * {@link #tryAdvance(java.util.function.DoubleConsumer)}; otherwise * the action is adapted to an instance of {@code DoubleConsumer}, by * boxing the argument of {@code DoubleConsumer}, and then passed to * {@link #tryAdvance(java.util.function.DoubleConsumer)}. @Override default boolean tryAdvance(Consumer
action) { if (action instanceof DoubleConsumer) { return tryAdvance((DoubleConsumer) action); } else { if (Tripwire.ENABLED) Tripwire.trip(getClass(), "{0} calling Spliterator.OfDouble.tryAdvance((DoubleConsumer) action::accept)"); return tryAdvance((DoubleConsumer) action::accept); } } * {@inheritDoc} * @implSpec * If the action is an instance of {@code DoubleConsumer} then it is * cast to {@code DoubleConsumer} and passed to * {@link #forEachRemaining(java.util.function.DoubleConsumer)}; * otherwise the action is adapted to an instance of * {@code DoubleConsumer}, by boxing the argument of * {@code DoubleConsumer}, and then passed to * {@link #forEachRemaining(java.util.function.DoubleConsumer)}. @Override default void forEachRemaining(Consumer
action) { if (action instanceof DoubleConsumer) { forEachRemaining((DoubleConsumer) action); } else { if (Tripwire.ENABLED) Tripwire.trip(getClass(), "{0} calling Spliterator.OfDouble.forEachRemaining((DoubleConsumer) action::accept)"); forEachRemaining((DoubleConsumer) action::accept); } } }}*/

六、Consumer 与 IntConsumer 的强制类型转换测试

// 六、Consumer 与 IntConsumer 的强制类型转换测试// 传入面向对象   对象this.action(intConsumer);// 传入Lambda表达式 函数式编程this.action(intConsumer::accept);this.action(value -> intConsumer.accept(value));this.action(consumer::accept);this.action(value -> consumer.accept(value));// 面向对象强制类型转换 报错java.lang.ClassCastException// this.action((IntConsumer) consumer);// this.action(((IntConsumer) consumer)::accept);// this.action(t -> ((IntConsumer) consumer).accept(t));// 函数式编程强制类型转换 Lambda表达式没变this.action((IntConsumer) consumer::accept);this.action((IntConsumer) (t -> consumer.accept(t)));this.action((IntConsumer) t -> consumer.accept(t));

七、Iterator-based Spliterators 与 StreamSupport底层实现

// 七、Iterator-based Spliterators 与 StreamSupport底层实现// Iterator-based Spliterators/* * A Spliterator using a given Iterator for element * operations. The spliterator implements {@code trySplit} to * permit limited parallelism. * spliterator利用trySplit实现有限的并行化操作 * * static class IteratorSpliterator
implements Spliterator
{} *//* * Low-level utility methods for creating and manipulating streams. * 用于创建和操作流的底层实用程序方法 * *

This class is mostly for library writers presenting stream views * of data structures; most static stream methods intended for end users are in * the various {@code Stream} classes. * StreamSupport提供数据结构的流视图的library 大多数为终端用户使用的静态流方法在Stream类中 * * @since 1.8 * public final class StreamSupport { * Creates a new sequential or parallel {@code Stream} from a * {@code Spliterator}. * * *

The spliterator is only traversed, split, or queried for estimated * size after the terminal operation of the stream pipeline commences. * 仅在流管道的终端操作开始后,才遍历、拆分或查询spliterator的估计大小。 * *

It is strongly recommended the spliterator report a characteristic of * {@code IMMUTABLE} or {@code CONCURRENT}, or be * late-binding. Otherwise, * {@link #stream(java.util.function.Supplier, int, boolean)} should be used * to reduce the scope of potential interference with the source. See * Non-Interference for * more details. * 强烈建议对spliterator设置characteristic(IMMUTABLE CONCURRENT late-binding) * 以减少潜在的干扰源范围 * public static

Stream
stream(Spliterator
spliterator, boolean parallel) { Objects.requireNonNull(spliterator); return new ReferencePipeline.Head<>(spliterator, StreamOpFlag.fromCharacteristics(spliterator), parallel); }}*/

八、流源分析

// 八、流源分析 /* 流源的创建 Abstract base class for an intermediate pipeline stage or pipeline source stage implementing whose elements are of type {@code U}. 抽象基类:用于实现其元素类型为{@code U}的中间管道阶段或管道源阶段 ReferencePipeline 操作引用类型 (将源阶段 与 [0,n)个中间操作阶段 看做一个对象) * @param 
type of elements in the upstream source * @param
type of elements in produced by this stage abstract class ReferencePipeline
extends AbstractPipeline
> implements Stream
{ * 源阶段 * Source stage of a ReferencePipeline. * * @param
type of elements in the upstream source * @param
type of elements in produced by this stage ReferencePipeline中静态内部类Head static class Head
extends ReferencePipeline
* * 注意: * 流本身不持有数据 * 数据的持有者:流的数据源(集合、数组等) * 流关注对数据的计算 *//* 抽象基类: 抽象管道AbstractPipeline 流接口及 其特化的核心实现 管理流管道 创建 与 评估 * Abstract base class for "pipeline" classes, which are the core * implementations of the Stream interface and its primitive specializations. * Manages construction and evaluation of stream pipelines. * *

A concrete intermediate stage is generally built from an * {@code AbstractPipeline}, a shape-specific pipeline class which extends it * (e.g., {@code IntPipeline}) which is also abstract, and an operation-specific * concrete class which extends that. {@code AbstractPipeline} contains most of * the mechanics of evaluating the pipeline, and implements methods that will be * used by the operation; the shape-specific classes add helper methods for * dealing with collection of results into the appropriate shape-specific * containers. * * *

After chaining a new intermediate operation, or executing a terminal * operation, the stream is considered to be consumed, and no more intermediate * or terminal operations are permitted on this stream instance. * 在链式添加中间操作或一个终止操作后 流视做被消费 * 流只能被消费一次 已消费-->不允许在此流实例中存在更多的中间操作或终止操作 * * @implNote *

For sequential streams, and parallel streams without * stateful intermediate * operations, parallel streams, pipeline evaluation is done in a single * pass that "jams" all the operations together. For parallel streams with * stateful operations, execution is divided into segments, where each * stateful operations marks the end of a segment, and each segment is * evaluated separately and the result used as the input to the next * segment. In all cases, the source data is not consumed until a terminal * operation begins. * 串行流 与 无状态的并行流 * 流的消费 是将中间的操作进行“jams”(打包放一起)对流中每个元素执行action-->single pass * * 有状态的并行流 * 执行分成segments 分别对segment执行有状态操作 并将其结果作为下一个segment输入 * * 在任何情况下,有且只有在一个终止操作被调用时 流真正被消费 abstract class AbstractPipeline

> extends PipelineHelper
implements BaseStream
AbstractPipeline的构造方法 AbstractPipeline(Supplier
> source, int sourceFlags, boolean parallel) {} AbstractPipeline(Spliterator
source, int sourceFlags, boolean parallel) {} 同一时间构造同一个AbstractPipeline 有且只有调用AbstractPipeline构造方法之一 sourceSpliterator与sourceSupplier 同一时间只能存在其一 当流被消费后 若not null 要设置为null 只能被消费一次 private Spliterator
sourceSpliterator; private Supplier
> sourceSupplier; *//* 针对于流源的foreach Optimized sequential terminal operations for the head of the pipeline @Override public void forEach(Consumer
action) { if (!isParallel()) { sourceStageSpliterator().forEachRemaining(action); } else { super.forEach(action); } } Terminal operations from Stream @Override public void forEach(Consumer
action) { evaluate(ForEachOps.makeRef(action, false)); } */

九、Array.asList()流源遍历注意事项

// 九、Array.asList()流源遍历注意事项        /*        为什么 未调用IteratorSpliterator.forEachRemaining()        list.stream().forEach(System.out::println); 执行过程分析        Arrays.asList()        private static class ArrayList
extends AbstractList
implements RandomAccess, java.io.Serializable{ private final E[] a; ArrayList(E[] array) { a = Objects.requireNonNull(array); } @Override public Spliterator
spliterator() { return Spliterators.spliterator(a, Spliterator.ORDERED); } } public static
Spliterator
spliterator(Object[] array, int additionalCharacteristics) { return new ArraySpliterator<>(Objects.requireNonNull(array), additionalCharacteristics); } @Override public void forEach(Consumer
action) { if (!isParallel()) { sourceStageSpliterator().forEachRemaining(action); } else { super.forEach(action); } } @SuppressWarnings("unchecked") @Override public void forEachRemaining(Consumer
action) { Object[] a; int i, hi; // hoist accesses and checks from loop if (action == null) throw new NullPointerException(); if ((a = array).length >= (hi = fence) && (i = index) >= 0 && i < (index = hi)) { do { action.accept((T)a[i]); } while (++i < hi); } }*/ System.out.println(list.getClass()); // Arrays中静态内部类ArrayList (class java.util.Arrays$ArrayList) // @Override public Spliterator
spliterator(){} // 调用ArraySpliterator.forEachRemaining()实现 list.stream().forEach(System.out::println); // 普通集合遍历 Iterable 中的 forEach // 效率高 list.forEach(System.out::println); }}

十、测试结果

.   ____          _            __ _ _ /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ \\/  ___)| |_)| | | | | || (_| |  ) ) ) )  '  |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot ::        (v2.1.2.RELEASE)2019-02-20 18:09:13.662  INFO 2224 --- [           main] c.j.d.j.S.S.B.SpliteratorDetail          : Starting SpliteratorDetail on DESKTOP-87RMBG4 with PID 2224 (started by 46250 in E:\IdeaProjects\design)2019-02-20 18:09:13.663  INFO 2224 --- [           main] c.j.d.j.S.S.B.SpliteratorDetail          : No active profile set, falling back to default profiles: default2019-02-20 18:09:14.133  INFO 2224 --- [           main] c.j.d.j.S.S.B.SpliteratorDetail          : Started SpliteratorDetail in 0.653 seconds (JVM running for 1.335)100100100100100100100100class java.util.Arrays$ArrayListKiritoAsunaSinonYuukiAliceKiritoAsunaSinonYuukiAlice

转载地址:http://trrja.baihongyu.com/

你可能感兴趣的文章
JavaScript变量和作用域
查看>>
JS 对象机制深剖——new 运算符
查看>>
10大托管国家和5大危险电子邮件主题
查看>>
Go嵌入类型及内部提升样例
查看>>
《软件工艺师:专业、务实、自豪》一3.7.4 软件工艺社团
查看>>
jQuery获取数组对象的值
查看>>
Android+struts2+json方式模拟手机登录功能
查看>>
#大学#汇编指令查询
查看>>
mono for android software自动更新
查看>>
版本管理工具——Git和TortoiseGit(乌龟Git)
查看>>
开源SIP服务器加密软件NethidPro升级
查看>>
linux的简单命令
查看>>
我的友情链接
查看>>
大型网站技术架构(一)大型网站架构演化
查看>>
百度页面分享插件源代码
查看>>
易宝典文章——玩转Office 365中的Exchange Online服务 之六 了解Exchange Online对于邮箱使用的限制...
查看>>
确定jdk是32位版本还是64位版本
查看>>
linux下文件删除的原理
查看>>
python os.path模块
查看>>
评"抄袭就是生产力:评中国盛行的成功学逻辑"
查看>>