Stream底层的实现

Stream接口实现了 BaseStream 接口,我们先来看看BaseStream的定义

BaseStream

BaseStream是所有流的父类接口。

对JavaDoc做一次解读,了解提供的所有方法。

  1. /**
  2. * Base interface for streams, which are sequences of elements supporting
  3. * sequential and parallel aggregate operations. The following example
  4. * illustrates an aggregate operation using the stream types {@link Stream}
  5. * and {@link IntStream}, computing the sum of the weights of the red widgets:
  6. *
  7. * <pre>{@code
  8. * int sum = widgets.stream()
  9. * .filter(w -> w.getColor() == RED)
  10. * .mapToInt(w -> w.getWeight())
  11. * .sum();
  12. * }</pre>
  13. *
  14. * See the class documentation for {@link Stream} and the package documentation
  15. * for <a href="package-summary.html">java.util.stream</a> for additional
  16. * specification of streams, stream operations, stream pipelines, and
  17. * parallelism, which governs the behavior of all stream types.
  18. *
  19. * @param <T> the type of the stream elements
  20. * @param <S> the type of of the stream implementing {@code BaseStream}
  21. S 代表中间操作产生的新的流操作。
  22. * @since 1.8
  23. * @see Stream
  24. * @see IntStream
  25. * @see LongStream
  26. * @see DoubleStream
  27. * @see <a href="package-summary.html">java.util.stream</a>
  28. */
  29. public interface BaseStream<T, S extends BaseStream<T, S>>
  30. extends AutoCloseable {
  31. /**
  32. * Returns an iterator for the elements of this stream.
  33. *
  34. * <p>This is a <a href="package-summary.html#StreamOps">terminal
  35. * operation</a>.
  36. *
  37. * @return the element iterator for this stream
  38. */
  39. Iterator<T> iterator(); //迭代器 ,针对于流中元素类型*(T)的迭代器
  40. /**
  41. * Returns a spliterator for the elements of this stream.
  42. *
  43. * <p>This is a <a href="package-summary.html#StreamOps">terminal
  44. * operation</a>.
  45. *
  46. * @return the element spliterator for this stream
  47. */
  48. Spliterator<T> spliterator(); //分割迭代器, 流中的核心的操作。
  49. /**
  50. * Returns whether this stream, if a terminal operation were to be executed,
  51. * would execute in parallel. Calling this method after invoking an
  52. * terminal stream operation method may yield unpredictable results.
  53. *
  54. * @return {@code true} if this stream would execute in parallel if executed
  55. */
  56. boolean isParallel(); //是否并行
  57. /**
  58. * Returns an equivalent stream that is sequential. May return
  59. * itself, either because the stream was already sequential, or because
  60. * the underlying stream state was modified to be sequential.,.
  61. 返回一个等价的串行流,有可能返回流本身,或者是流修改成串行流的
  62. *
  63. * <p>This is an <a href="package-summary.html#StreamOps">intermediate
  64. * operation</a>.
  65. *
  66. * @return a sequential stream
  67. */
  68. S sequential(); //返回值为S:流,新的流对象
  69. /**
  70. * Returns an equivalent stream that is parallel. May return
  71. * itself, either because the stream was already parallel, or because
  72. * the underlying stream state was modified to be parallel.
  73. *
  74. * <p>This is an <a href="package-summary.html#StreamOps">intermediate
  75. * operation</a>.
  76. *
  77. * @return a parallel stream
  78. */
  79. S parallel();
  80. /**
  81. * Returns an equivalent stream that is
  82. * <a href="package-summary.html#Ordering">unordered</a>. May return
  83. * itself, either because the stream was already unordered, or because
  84. * the underlying stream state was modified to be unordered.
  85. *
  86. * <p>This is an <a href="package-summary.html#StreamOps">intermediate
  87. * operation</a>.
  88. *
  89. * @return an unordered stream
  90. */
  91. S unordered();
  92. /**
  93. * Returns an equivalent stream with an additional close handler. Close
  94. * handlers are run when the {@link #close()} method
  95. * is called on the stream, and are executed in the order they were
  96. * added. All close handlers are run, even if earlier close handlers throw
  97. * exceptions. If any close handler throws an exception, the first
  98. * exception thrown will be relayed to the caller of {@code close()}, with
  99. * any remaining exceptions added to that exception as suppressed exceptions
  100. * (unless one of the remaining exceptions is the same exception as the
  101. * first exception, since an exception cannot suppress itself.) May
  102. * return itself.
  103. 返回值为流。流中带了一个关闭处理器、关闭处理器调用的是 close()方法。
  104. 按照被添加的顺序去关闭。
  105. *
  106. * <p>This is an <a href="package-summary.html#StreamOps">intermediate
  107. * operation</a>.
  108. *
  109. * @param closeHandler A task to execute when the stream is closed
  110. * @return a stream with a handler that is run if the stream is closed
  111. */
  112. S onClose(Runnable closeHandler);
  113. /**
  114. * Closes this stream, causing all close handlers for this stream pipeline
  115. * to be called.
  116. *
  117. * @see AutoCloseable#close()
  118. */
  119. @Override
  120. void close();
  121. }

对onClose关闭处理器做单独的认识

  1. public class StreamTest2 {
  2. public static void main(String[] args) {
  3. List<String> list = Arrays.asList("hello", "world", "hello world");
  4. // list.stream().onClose(()-> System.out.println("aaa")).onClose(()-> System.out.println("bbb")).forEach(System.out::println);
  5. try (Stream<String> stream = list.stream()){
  6. stream.onClose(()-> {
  7. System.out.println("aaa");
  8. throw new NullPointerException("first Exception");
  9. }).onClose(()->{
  10. System.out.println("bbb");
  11. throw new ArithmeticException("first Exception");
  12. }).forEach(System.out::println);
  13. }
  14. }
  15. }
  1. Exception in thread "main" java.lang.NullPointerException: first Exception
  2. at com.dawa.jdk8.StreamTest2.lambda$main$0(StreamTest2.java:21)
  3. at java.util.stream.Streams$1.run(Streams.java:850)
  4. at java.util.stream.AbstractPipeline.close(AbstractPipeline.java:323)
  5. at com.dawa.jdk8.StreamTest2.main(StreamTest2.java:26)
  6. Suppressed: java.lang.ArithmeticException: first Exception
  7. at com.dawa.jdk8.StreamTest2.lambda$main$1(StreamTest2.java:24)
  8. at java.util.stream.Streams$1.run(Streams.java:854)
  9. ... 2 more

几种可能的情况

  1. //运行结果就可以看到 aa,bbb被调用。
  2. //也可以看到压制异常
  3. //如果两个地方的异常是相同的异常对象,则第二个异常不会被压制。因为异常是自己不会压制自己的。
  4. //如果是同一种异常,但是不是同一个异常,还是会压制的。

备注:遇到问题,javadoc里面已经写的很清楚了。往往每个人都伸手可得的内容,容易最被忽视掉。

Stream源码分析

引入Example,跟源码。

  1. public static void main(String[] args) {
  2. List<String> list = Arrays.asList("hello", "world", "hello world");
  3. list.stream().forEach(System.out::println);
  4. }

1. stream()

来自Collection接口中的默认方法。

  1. /**
  2. * Returns a sequential {@code Stream} with this collection as its source.
  3. *
  4. * <p>This method should be overridden when the {@link #spliterator()}
  5. * method cannot return a spliterator that is {@code IMMUTABLE},
  6. * {@code CONCURRENT}, or <em>late-binding</em>. (See {@link #spliterator()}
  7. * for details.)
  8. 当这个 spliterator()无法返回这三个(不可变的,并行的,延迟绑定的)类型中的一个的话,
  9. 这个方法需要被重写。
  10. *
  11. * @implSpec
  12. * The default implementation creates a sequential {@code Stream} from the
  13. * collection's {@code Spliterator}.
  14. 返回一个针对于当前元素的一个串行流。
  15. *
  16. * @return a sequential {@code Stream} over the elements in this collection
  17. * @since 1.8
  18. */
  19. default Stream<E> stream() {
  20. return StreamSupport.stream(spliterator(), false);
  21. }

所以,这里就要先了解一下spliterator()这个方法是怎么实现的。

spliterator()的源码实现

实现方法和stream()一样,在Collection接口中的默认方法

  1. /**
  2. * Creates a {@link Spliterator} over the elements in this collection.
  3. *
  4. * Implementations should document characteristic values reported by the
  5. * spliterator. Such characteristic values are not required to be reported
  6. * if the spliterator reports {@link Spliterator#SIZED} and this collection
  7. * contains no elements.
  8. Spliterator#SIZED,集合,固定大小,并且没有值。的时候是不用报告的。
  9. --备注:和collectors的characteristic特性值
  10. *
  11. * <p>The default implementation should be overridden by subclasses that
  12. * can return a more efficient spliterator. In order to
  13. * preserve expected laziness behavior for the {@link #stream()} and
  14. * {@link #parallelStream()}} methods, spliterators should either have the
  15. * characteristic of {@code IMMUTABLE} or {@code CONCURRENT}, or be
  16. * <em><a href="Spliterator.html#binding">late-binding</a></em>.
  17. * If none of these is practical, the overriding class should describe the
  18. * spliterator's documented policy of binding and structural interference,
  19. * and should override the {@link #stream()} and {@link #parallelStream()}
  20. * methods to create streams using a {@code Supplier} of the spliterator,
  21. * as in:
  22. 默认的实现,应该被子类所重写。为了保留期望的stream()的延迟行为。分割迭代器的特性值 只有在满足{@code IMMUTABLE} or {@code CONCURRENT}的时候,才是具有延迟行为的。
  23. 如果上面条件都无法做的话,重写的类应该去描述这个分割迭代器的文档
  24. 并且重写。
  25. 用下面的这种方式去定义。
  26. * <pre>{@code
  27. * Stream<E> s = StreamSupport.stream(() -> spliterator(), spliteratorCharacteristics)
  28. * }</pre>
  29. * <p>These requirements ensure that streams produced by the
  30. * {@link #stream()} and {@link #parallelStream()} methods will reflect the
  31. * contents of the collection as of initiation of the terminal stream
  32. * operation.
  33. 这些要求确保了由这两个方法生成的流,反应了流的内容 (在终止流操作执行的一瞬间)
  34. *
  35. * @implSpec
  36. * The default implementation creates a
  37. * <em><a href="Spliterator.html#binding">late-binding</a></em> spliterator
  38. * from the collections's {@code Iterator}. The spliterator inherits the
  39. * <em>fail-fast</em> properties of the collection's iterator.
  40. 默认的实现 从集合的迭代器中,创建一个延迟绑定的分割迭代器。 分割迭代器会继承迭代器的快速失败的属性。
  41. * <p>
  42. * The created {@code Spliterator} reports {@link Spliterator#SIZED}.
  43. 创建的分割迭代器,会携带一个 Spliterator#SIZED (固定大小的)的特性值
  44. *
  45. * @implNote
  46. * The created {@code Spliterator} additionally reports
  47. * {@link Spliterator#SUBSIZED}.
  48. 还会额外的增加一个Spliterator#SUBSIZED(子大小)的确定。
  49. *
  50. * <p>If a spliterator covers no elements then the reporting of additional
  51. * characteristic values, beyond that of {@code SIZED} and {@code SUBSIZED},
  52. * does not aid clients to control, specialize or simplify computation.
  53. * However, this does enable shared use of an immutable and empty
  54. * spliterator instance (see {@link Spliterators#emptySpliterator()}) for
  55. * empty collections, and enables clients to determine if such a spliterator
  56. * covers no elements.
  57. 如果分割迭代器里面没有元素,那么除了 {@code SIZED} and {@code SUBSIZED}之外其他的特性,对于计算的控制是没有帮助作用的。 不过可以促进空的迭代器的共享使用。 参见: Spliterators#emptySpliterator()、
  58. 对于一个空的迭代器可以判断是不是没有元素
  59. *
  60. * @return a {@code Spliterator} over the elements in this collection
  61. * @since 1.8
  62. */
  63. @Override
  64. default Spliterator<E> spliterator() {
  65. return Spliterators.spliterator(this, 0);
  66. }

那么,到底什么是分割迭代器? Spliterator

到底什么是分割迭代器 —— Spliterator类

和Collector收集器一样,同时提供了collector接口和 Collectors的工具类

  1. public final class Spliterators {}
  2. public interface Spliterator<T> {}

我们先来看看Spliterator接口的javadoc


  1. /**
  2. * An object for traversing and partitioning elements of a source. The source
  3. * of elements covered by a Spliterator could be, for example, an array, a
  4. * {@link Collection}, an IO channel, or a generator function.
  5. 一个分割迭代器,是一个对象,用于对源中的元素进行遍历和分区。
  6. 源可以是:数组,集合,或者IO通道
  7. *
  8. * <p>A Spliterator may traverse elements individually ({@link
  9. * #tryAdvance tryAdvance()}) or sequentially in bulk
  10. * ({@link #forEachRemaining forEachRemaining()}).
  11. 一个迭代器可以一个一个的去遍历。tryAdvance()
  12. 也可以以块的方式去遍历。 forEachRemaining()
  13. *
  14. * <p>A Spliterator may also partition off some of its elements (using
  15. * {@link #trySplit}) as another Spliterator, to be used in
  16. * possibly-parallel operations. Operations using a Spliterator that
  17. * cannot split, or does so in a highly imbalanced or inefficient
  18. * manner, are unlikely to benefit from parallelism. Traversal
  19. * and splitting exhaust elements; each Spliterator is useful for only a single
  20. * bulk computation.
  21. 也可以使用 trySplit() 对元素进行分区,形成一个新的元素迭代器。也可以以并行的方式去操作。
  22. 使用Spliterator的操作,是不能分割,或者效率非常低的分割, 如果用并行的话,不会获得很大的收益。
  23. (比如,100个元素,分区分为 2+98,这种的就是非常低效的。就无法利用并行的优势了。)
  24. 每一个分割迭代器,只对自己特定的块有用。
  25. *
  26. * <p>A Spliterator also reports a set of {@link #characteristics()} of its
  27. * structure, source, and elements from among {@link #ORDERED},
  28. * {@link #DISTINCT}, {@link #SORTED}, {@link #SIZED}, {@link #NONNULL},
  29. * {@link #IMMUTABLE}, {@link #CONCURRENT}, and {@link #SUBSIZED}. These may
  30. * be employed by Spliterator clients to control, specialize or simplify
  31. * computation. For example, a Spliterator for a {@link Collection} would
  32. * report {@code SIZED}, a Spliterator for a {@link Set} would report
  33. * {@code DISTINCT}, and a Spliterator for a {@link SortedSet} would also
  34. * report {@code SORTED}. Characteristics are reported as a simple unioned bit
  35. * set.
  36. 分割迭代器还会 设置 特性值
  37. {@link #ORDERED},
  38. {@link #DISTINCT},
  39. {@link #SORTED},
  40. {@link #SIZED},
  41. {@link #NONNULL},
  42. {@link #IMMUTABLE},
  43. {@link #CONCURRENT},
  44. {@link #SUBSIZED}.
  45. 这些属性用来控制特定的某些计算。
  46. 比如说,一个 Collection就需要SIZED特性值
  47. Set需要DISTINCT
  48. *
  49. * Some characteristics additionally constrain method behavior; for example if
  50. * {@code ORDERED}, traversal methods must conform to their documented ordering.
  51. * New characteristics may be defined in the future, so implementors should not
  52. * assign meanings to unlisted values.
  53. 不要给没有列出来的值赋予新的含义。
  54. *
  55. * <p><a name="binding">A Spliterator that does not report {@code IMMUTABLE} or
  56. * {@code CONCURRENT} is expected to have a documented policy concerning:
  57. * when the spliterator <em>binds</em> to the element source; and detection of
  58. * structural interference of the element source detected after binding.</a> A
  59. * <em>late-binding</em> Spliterator binds to the source of elements at the
  60. * point of first traversal, first split, or first query for estimated size,
  61. * rather than at the time the Spliterator is created. A Spliterator that is
  62. * not <em>late-binding</em> binds to the source of elements at the point of
  63. * construction or first invocation of any method. Modifications made to the
  64. * source prior to binding are reflected when the Spliterator is traversed.
  65. * After binding a Spliterator should, on a best-effort basis, throw
  66. * {@link ConcurrentModificationException} if structural interference is
  67. * detected. Spliterators that do this are called <em>fail-fast</em>. The
  68. * bulk traversal method ({@link #forEachRemaining forEachRemaining()}) of a
  69. * Spliterator may optimize traversal and check for structural interference
  70. * after all elements have been traversed, rather than checking per-element and
  71. * failing immediately.
  72. 并不是说一个迭代器在创建的时候就被绑定到源上面了。而是在满足首次遍历,首次分割,首次查询的时候,才进行绑定。
  73. ConcurrentModificationException,在绑定之前操作,会出现这一行的异常。
  74. 叫做 快速失败。
  75. *
  76. * <p>Spliterators can provide an estimate of the number of remaining elements
  77. * via the {@link #estimateSize} method. Ideally, as reflected in characteristic
  78. * {@link #SIZED}, this value corresponds exactly to the number of elements
  79. * that would be encountered in a successful traversal. However, even when not
  80. * exactly known, an estimated value value may still be useful to operations
  81. * being performed on the source, such as helping to determine whether it is
  82. * preferable to split further or traverse the remaining elements sequentially.
  83. *
  84. * <p>Despite their obvious utility in parallel algorithms, spliterators are not
  85. * expected to be thread-safe; instead, implementations of parallel algorithms
  86. * using spliterators should ensure that the spliterator is only used by one
  87. * thread at a time. This is generally easy to attain via <em>serial
  88. * thread-confinement</em>, which often is a natural consequence of typical
  89. * parallel algorithms that work by recursive decomposition. A thread calling
  90. * {@link #trySplit()} may hand over the returned Spliterator to another thread,
  91. * which in turn may traverse or further split that Spliterator. The behaviour
  92. * of splitting and traversal is undefined if two or more threads operate
  93. * concurrently on the same spliterator. If the original thread hands a
  94. * spliterator off to another thread for processing, it is best if that handoff
  95. * occurs before any elements are consumed with {@link #tryAdvance(Consumer)
  96. * tryAdvance()}, as certain guarantees (such as the accuracy of
  97. * {@link #estimateSize()} for {@code SIZED} spliterators) are only valid before
  98. * traversal has begun.
  99. *
  100. serial-thread-confinement : 线程安全围栏
  101. * <p>Primitive subtype specializations of {@code Spliterator} are provided for
  102. * {@link OfInt int}, {@link OfLong long}, and {@link OfDouble double} values.
  103. * The subtype default implementations of
  104. * {@link Spliterator#tryAdvance(java.util.function.Consumer)}
  105. * and {@link Spliterator#forEachRemaining(java.util.function.Consumer)} box
  106. * primitive values to instances of their corresponding wrapper class. Such
  107. * boxing may undermine any performance advantages gained by using the primitive
  108. * specializations. To avoid boxing, the corresponding primitive-based methods
  109. * should be used.
  110. tryAdvance()方法和forEachRemaining()
  111. 提供了原生子类型的特化, int, long, doule 等,子类型默认的实现。
  112. 避免包装类型装箱拆箱操作。
  113. 如下。
  114. For example, 如下特化版本.
  115. * {@link Spliterator.OfInt#tryAdvance(java.util.function.IntConsumer)}
  116. * and {@link Spliterator.OfInt#forEachRemaining(java.util.function.IntConsumer)}
  117. * should be used in preference to
  118. * {@link Spliterator.OfInt#tryAdvance(java.util.function.Consumer)} and
  119. * {@link Spliterator.OfInt#forEachRemaining(java.util.function.Consumer)}.
  120. * Traversal of primitive values using boxing-based methods
  121. * {@link #tryAdvance tryAdvance()} and
  122. * {@link #forEachRemaining(java.util.function.Consumer) forEachRemaining()}
  123. * does not affect the order in which the values, transformed to boxed values,
  124. * are encountered.
  125. *
  126. * @apiNote
  127. * <p>Spliterators, like {@code Iterator}s, are for traversing the elements of
  128. * a source. The {@code Spliterator} API was designed to support efficient
  129. * parallel traversal in addition to sequential traversal, by supporting
  130. * decomposition as well as single-element iteration. In addition, the
  131. * protocol for accessing elements via a Spliterator is designed to impose
  132. * smaller per-element overhead than {@code Iterator}, an d to avoid the inherent
  133. * race involved in having separate methods for {@code hasNext()} and
  134. * {@code next()}.
  135. Spliterator支持高效的,并行的操作。
  136. 支持解耦,分解,氮元素的遍历。
  137. 此外,通过accessing协议。。。 相对于 Iterator,遍历元素的时候成本更低。
  138. 原因: 之前的{@code hasNext()} and {@code next()}.搭配使用存在竞争。
  139. 现在直接使用一个tryAdvance()方法就解决了这两个方法实现的事情。
  140. *
  141. * <p>For mutable sources, arbitrary and non-deterministic behavior may occur if
  142. * the source is structurally interfered with (elements added, replaced, or
  143. * removed) between the time that the Spliterator binds to its data source and
  144. * the end of traversal. For example, such interference will produce arbitrary,
  145. * non-deterministic results when using the {@code java.util.stream} framework.
  146. 如果源在结构上被修改了(增删改),在绑定迭代器之后和执行完毕之前这段时间内进行任意修改。
  147. 行为就是不确定的了。
  148. 所以在使用流框架的时候,要求源是不可变的
  149. *
  150. * <p>Structural interference of a source can be managed in the following ways
  151. * (in approximate order of decreasing desirability):
  152. 源结构上的修改,是可以通过如下几个方式去修改的
  153. * <ul>
  154. * <li>The source cannot be structurally interfered with.
  155. 如,源是不允许被修改的。
  156. * <br>For example, an instance of
  157. * {@link java.util.concurrent.CopyOnWriteArrayList} is an immutable source.
  158. * A Spliterator created from the source reports a characteristic of
  159. * {@code IMMUTABLE}.</li>
  160. 如:CopyOnWriteArrayList是一个不可变的源。
  161. 先拷贝,再追加。 (但是效率会下降。)适合读多写少的操作。
  162. * <li>The source manages concurrent modifications.
  163. 源本身自己去管理并发。
  164. * <br>For example, a key set of a {@link java.util.concurrent.ConcurrentHashMap}
  165. * is a concurrent source. A Spliterator created from the source reports a
  166. * characteristic of {@code CONCURRENT}.</li>
  167. 如:ConcurrentHashMap 。 创建的是并发源
  168. * <li>The mutable source provides a late-binding and fail-fast Spliterator.
  169. * <br>Late binding narrows the window during which interference can affect
  170. * the calculation; fail-fast detects, on a best-effort basis, that structural
  171. * interference has occurred after traversal has commenced and throws
  172. * {@link ConcurrentModificationException}. For example, {@link ArrayList},
  173. * and many other non-concurrent {@code Collection} classes in the JDK, provide
  174. * a late-binding, fail-fast spliterator.</li>
  175. 可变的源提供了延迟绑定和快速失败的迭代分割器。
  176. 会限制时间点的缩短。
  177. 如果在遍历中修改,则会抛出ConcurrentModificationException。
  178. * <li>The mutable source provides a non-late-binding but fail-fast Spliterator.
  179. * <br>The source increases the likelihood of throwing
  180. * {@code ConcurrentModificationException} since the window of potential
  181. * interference is larger.</li>
  182. * <li>The mutable source provides a late-binding and non-fail-fast Spliterator.
  183. * <br>The source risks arbitrary, non-deterministic behavior after traversal
  184. * has commenced since interference is not detected.
  185. * </li>
  186. * <li>The mutable source provides a non-late-binding and non-fail-fast
  187. * Spliterator.
  188. * <br>The source increases the risk of arbitrary, non-deterministic behavior
  189. * since non-detected interference may occur after construction.
  190. * </li>
  191. 总结。
  192. 1. 源是不是并发的
  193. 2. 是不是快速绑定的,是不是快速失败的(2*2 组合的四种情况。)
  194. * </ul>
  195. *
  196. 串行案例
  197. * <p><b>Example.</b> Here is a class (not a very useful one, except
  198. * for illustration) that maintains an array in which the actual data
  199. * are held in even locations, and unrelated tag data are held in odd
  200. * locations. Its Spliterator ignores the tags.
  201. 如:类维护了一个数组。 实际的数据是在偶数的位置上存放。不想管的标签数据是存放在奇数位置上。
  202. *
  203. * <pre> {@code
  204. * class TaggedArray<T> {
  205. * private final Object[] elements; // immutable after construction
  206. * TaggedArray(T[] data, Object[] tags) {
  207. * int size = data.length;
  208. * if (tags.length != size) throw new IllegalArgumentException();
  209. * this.elements = new Object[2 * size];
  210. * for (int i = 0, j = 0; i < size; ++i) {
  211. * elements[j++] = data[i];
  212. * elements[j++] = tags[i];
  213. * }
  214. * }
  215. *
  216. * public Spliterator<T> spliterator() {
  217. * return new TaggedArraySpliterator<>(elements, 0, elements.length);
  218. * }
  219. *
  220. * static class TaggedArraySpliterator<T> implements Spliterator<T> {
  221. * private final Object[] array;
  222. * private int origin; // current index, advanced on split or traversal
  223. * private final int fence; // one past the greatest index
  224. *
  225. * TaggedArraySpliterator(Object[] array, int origin, int fence) {
  226. * this.array = array; this.origin = origin; this.fence = fence;
  227. * }
  228. *
  229. * public void forEachRemaining(Consumer<? super T> action) {
  230. * for (; origin < fence; origin += 2)
  231. * action.accept((T) array[origin]);
  232. * }
  233. *
  234. * public boolean tryAdvance(Consumer<? super T> action) {
  235. * if (origin < fence) {
  236. * action.accept((T) array[origin]);
  237. * origin += 2;
  238. * return true;
  239. * }
  240. * else // cannot advance
  241. * return false;
  242. * }
  243. *
  244. * public Spliterator<T> trySplit() {
  245. * int lo = origin; // divide range in half
  246. * int mid = ((lo + fence) >>> 1) & ~1; // force midpoint to be even
  247. * if (lo < mid) { // split out left half
  248. * origin = mid; // reset this Spliterator's origin
  249. * return new TaggedArraySpliterator<>(array, lo, mid);
  250. * }
  251. * else // too small to split
  252. * return null;
  253. * }
  254. *
  255. * public long estimateSize() {
  256. * return (long)((fence - origin) / 2);
  257. * }
  258. *
  259. * public int characteristics() {
  260. * return ORDERED | SIZED | IMMUTABLE | SUBSIZED;
  261. * }
  262. * }
  263. * }}</pre>
  264. *
  265. 并行案例:
  266. * <p>As an example how a parallel computation framework, such as the
  267. * {@code java.util.stream} package, would use Spliterator in a parallel
  268. * computation, here is one way to implement an associated parallel forEach,
  269. * that illustrates the primary usage idiom of splitting off subtasks until
  270. * the estimated amount of work is small enough to perform
  271. * sequentially. Here we assume that the order of processing across
  272. * subtasks doesn't matter; different (forked) tasks may further split
  273. * and process elements concurrently in undetermined order. This
  274. * example uses a {@link java.util.concurrent.CountedCompleter};
  275. * similar usages apply to other parallel task constructions.
  276. *
  277. * <pre>{@code
  278. * static <T> void parEach(TaggedArray<T> a, Consumer<T> action) {
  279. * Spliterator<T> s = a.spliterator();
  280. * long targetBatchSize = s.estimateSize() / (ForkJoinPool.getCommonPoolParallelism() * 8);
  281. * new ParEach(null, s, action, targetBatchSize).invoke();
  282. * }
  283. *
  284. * static class ParEach<T> extends CountedCompleter<Void> {
  285. * final Spliterator<T> spliterator;
  286. * final Consumer<T> action;
  287. * final long targetBatchSize;
  288. *
  289. * ParEach(ParEach<T> parent, Spliterator<T> spliterator,
  290. * Consumer<T> action, long targetBatchSize) {
  291. * super(parent);
  292. * this.spliterator = spliterator; this.action = action;
  293. * this.targetBatchSize = targetBatchSize;
  294. * }
  295. *
  296. * public void compute() {
  297. * Spliterator<T> sub;
  298. * while (spliterator.estimateSize() > targetBatchSize &&
  299. * (sub = spliterator.trySplit()) != null) {
  300. * addToPendingCount(1);
  301. * new ParEach<>(this, sub, action, targetBatchSize).fork();
  302. * }
  303. * spliterator.forEachRemaining(action);
  304. * propagateCompletion();
  305. * }
  306. * }}</pre>
  307. *
  308. * @implNote
  309. * If the boolean system property {@code org.openjdk.java.util.stream.tripwire}
  310. * is set to {@code true} then diagnostic warnings are reported if boxing of
  311. * primitive values occur when operating on primitive subtype specializations.
  312. *
  313. * @param <T> the type of elements returned by this Spliterator
  314. *
  315. * @see Collection
  316. * @since 1.8
  317. */
  • serial-thread-confinement

我们再来看看Spliterator类中的方法

  1. tryAdvance() 尝试遍历,对元素执行动作。
  1. /**
  2. * If a remaining element exists, performs the given action on it,
  3. * returning {@code true}; else returns {@code false}. If this
  4. * Spliterator is {@link #ORDERED} the action is performed on the
  5. * next element in encounter order. Exceptions thrown by the
  6. * action are relayed to the caller.
  7. *
  8. * @param action The action
  9. * @return {@code false} if no remaining elements existed
  10. * upon entry to this method, else {@code true}.
  11. * @throws NullPointerException if the specified action is null
  12. */
  13. boolean tryAdvance(Consumer<? super T> action);
  1. forEachRemaining() 。通过函数式接口 调用tryAdvance().
  1. /**
  2. * Performs the given action for each remaining element, sequentially in
  3. * the current thread, until all elements have been processed or the action
  4. * throws an exception. If this Spliterator is {@link #ORDERED}, actions
  5. * are performed in encounter order. Exceptions thrown by the action
  6. * are relayed to the caller.
  7. *
  8. * @implSpec
  9. * The default implementation repeatedly invokes {@link #tryAdvance} until
  10. * it returns {@code false}. It should be overridden whenever possible.
  11. *
  12. * @param action The action
  13. * @throws NullPointerException if the specified action is null
  14. */
  15. default void forEachRemaining(Consumer<? super T> action) {
  16. do { } while (tryAdvance(action));
  17. }
  1. trySplit() 尝试进行分割
  1. /**
  2. * If this spliterator can be partitioned, returns a Spliterator
  3. * covering elements, that will, upon return from this method, not
  4. * be covered by this Spliterator.
  5. 如果这个分割迭代器能够被进行分割。就会返回一个 涵盖这个元素的Spliterator,
  6. 分割出来的新的Spliterator可能会被继续分割,剩下的继续又当前的Spliterator涵盖
  7. *
  8. * <p>If this Spliterator is {@link #ORDERED}, the returned Spliterator
  9. * must cover a strict prefix of the elements.
  10. 如果 Spliterator is {@link #ORDERED}。返回的必须是ORDERED的
  11. *
  12. * <p>Unless this Spliterator covers an infinite number of elements,
  13. * repeated calls to {@code trySplit()} must eventually return {@code null}.
  14. 除非这个 Spliterator 涵盖的事一个无限的元素。
  15. 否则,必须被确认返回个数是确定的。
  16. 重复的去继续分割,分割到不能再分割。 (一定会有这样的情况。)
  17. * Upon non-null return:
  18. * <ul>
  19. * <li>the value reported for {@code estimateSize()} before splitting,
  20. * must, after splitting, be greater than or equal to {@code estimateSize()}
  21. * for this and the returned Spliterator; and</li>
  22. * <li>if this Spliterator is {@code SUBSIZED}, then {@code estimateSize()}
  23. * for this spliterator before splitting must be equal to the sum of
  24. * {@code estimateSize()} for this and the returned Spliterator after
  25. * splitting.</li>
  26. * </ul>
  27. 如果不会空:
  28. 分割前的 estimateSize()的返回值,必须大于等于分割之后estimateSize()的返回值。
  29. 如果 Spliterator is {@code SUBSIZED},那么 分割之前 estimateSize()的大小,必须等于 分割之后的 estimateSize() 和返回来的值的大小。(分割前后:必须 8 = 4+4.)
  30. *
  31. * <p>This method may return {@code null} for any reason,
  32. * including emptiness, inability to split after traversal has
  33. * commenced, data structure constraints, and efficiency
  34. * considerations.
  35. 这个放个出于以下原因,都会返回Null值
  36. 1. emptiness
  37. *
  38. * @apiNote
  39. * An ideal {@code trySplit} method efficiently (without
  40. * traversal) divides its elements exactly in half, allowing
  41. * balanced parallel computation. Many departures from this ideal
  42. * remain highly effective; for example, only approximately
  43. * splitting an approximately balanced tree, or for a tree in
  44. * which leaf nodes may contain either one or two elements,
  45. * failing to further split these nodes. However, large
  46. * deviations in balance and/or overly inefficient {@code
  47. * trySplit} mechanics typically result in poor parallel
  48. * performance.
  49. @API文档
  50. 一种理想的trySplit()方法,会恰好将元素分为两半。允许平衡的并行计算。
  51. 很多情况下违背了这种理想的情况。
  52. 比如说:只是分割一个嫉妒不平衡的一个数,数中只有两个节点。等。不能再次进行分割。
  53. 然而,很不平衡的这种机制,会导致并发效率的极度降低。
  54. *
  55. * @return a {@code Spliterator} covering some portion of the
  56. * elements, or {@code null} if this spliterator cannot be split
  57. 返回一个Spliterator
  58. */
  59. Spliterator<T> trySplit();
  1. estimateSize() 估算大小。
  1. /**
  2. * Returns an estimate of the number of elements that would be
  3. * encountered by a {@link #forEachRemaining} traversal, or returns {@link
  4. * Long#MAX_VALUE} if infinite, unknown, or too expensive to compute.
  5. 返回元素数量的估算值。(会被forEachRemaining 遍历的元素)
  6. infinite, unknown, or too expensive to compute.这几种情况会返回:MAX_VALUE
  7. *
  8. * <p>If this Spliterator is {@link #SIZED} and has not yet been partially
  9. * traversed or split, or this Spliterator is {@link #SUBSIZED} and has
  10. * not yet been partially traversed, this estimate must be an accurate
  11. * count of elements that would be encountered by a complete traversal.
  12. * Otherwise, this estimate may be arbitrarily inaccurate, but must decrease
  13. * as specified across invocations of {@link #trySplit}.
  14. 如果Spliterator是SIZED 或者是SUBSIZED 。那个 这个元素的estimate值一定是精确的。
  15. 然而,必须要减少 trySplit 的调用。
  16. *
  17. * @apiNote
  18. * Even an inexact estimate is often useful and inexpensive to compute.
  19. * For example, a sub-spliterator of an approximately balanced binary tree
  20. * may return a value that estimates the number of elements to be half of
  21. * that of its parent; if the root Spliterator does not maintain an
  22. * accurate count, it could estimate size to be the power of two
  23. * corresponding to its maximum depth.
  24. 甚至一个不太精确的估算,也是有用的。
  25. *
  26. * @return the estimated size, or {@code Long.MAX_VALUE} if infinite,
  27. * unknown, or too expensive to compute.
  28. */
  29. long estimateSize();
  1. getExactSizeIfKnown() 如果知道的话就会返回确定的大小。
  1. /**
  2. * Convenience method that returns {@link #estimateSize()} if this
  3. * Spliterator is {@link #SIZED}, else {@code -1}.
  4. 如果Spliterator是SIZED的话, estimateSize就会返回确定的大小。
  5. * @implSpec
  6. * The default implementation returns the result of {@code estimateSize()}
  7. * if the Spliterator reports a characteristic of {@code SIZED}, and
  8. * {@code -1} otherwise.
  9. *
  10. * @return the exact size, if known, else {@code -1}.
  11. */
  12. default long getExactSizeIfKnown() {
  13. return (characteristics() & SIZED) == 0 ? -1L : estimateSize();
  14. }
  1. characteristics() 特性值。
  1. /**
  2. * Returns a set of characteristics of this Spliterator and its
  3. * elements. The result is represented as ORed values from {@link
  4. * #ORDERED}, {@link #DISTINCT}, {@link #SORTED}, {@link #SIZED},
  5. * {@link #NONNULL}, {@link #IMMUTABLE}, {@link #CONCURRENT},
  6. * {@link #SUBSIZED}. Repeated calls to {@code characteristics()} on
  7. * a given spliterator, prior to or in-between calls to {@code trySplit},
  8. * should always return the same result.
  9. 返回这个Spliterator的特性值的集合。
  10. {@link#ORDERED},
  11. {@link #DISTINCT},
  12. {@link #SORTED},
  13. {@link #SIZED},
  14. {@link #NONNULL},
  15. {@link #IMMUTABLE},
  16. {@link #CONCURRENT},
  17. {@link #SUBSIZED}
  18. 这8个,在下面有定义。
  19. *
  20. * <p>If a Spliterator reports an inconsistent set of
  21. * characteristics (either those returned from a single invocation
  22. * or across multiple invocations), no guarantees can be made
  23. * about any computation using this Spliterator.
  24. *
  25. * @apiNote The characteristics of a given spliterator before splitting
  26. * may differ from the characteristics after splitting. For specific
  27. * examples see the characteristic values {@link #SIZED}, {@link #SUBSIZED}
  28. * and {@link #CONCURRENT}.
  29. 具体的例子看下面的说明。
  30. *
  31. * @return a representation of characteristics
  32. */
  33. int characteristics();
  1. hasCharacteristics(int characteristics) 查看是否包含给定的特性值
  1. /**
  2. * Returns {@code true} if this Spliterator's {@link
  3. * #characteristics} contain all of the given characteristics.
  4. *
  5. * @implSpec
  6. * The default implementation returns true if the corresponding bits
  7. * of the given characteristics are set.
  8. *
  9. * @param characteristics the characteristics to check for
  10. * @return {@code true} if all the specified characteristics are present,
  11. * else {@code false}
  12. */
  13. default boolean hasCharacteristics(int characteristics) {
  14. return (characteristics() & characteristics) == characteristics;
  15. }
  1. getComparator() :抛出一个不可实现的状态异常。
  1. /**
  2. * If this Spliterator's source is {@link #SORTED} by a {@link Comparator},
  3. * returns that {@code Comparator}. If the source is {@code SORTED} in
  4. * {@linkplain Comparable natural order}, returns {@code null}. Otherwise,
  5. * if the source is not {@code SORTED}, throws {@link IllegalStateException}.
  6. 如果源是有序的,返回用于排序的 Comparator
  7. 如果是按照自然排序的,就返回空 (就不需要比较器)
  8. 否则就抛出异常,
  9. *
  10. * @implSpec
  11. * The default implementation always throws {@link IllegalStateException}.
  12. *
  13. * @return a Comparator, or {@code null} if the elements are sorted in the
  14. * natural order.
  15. * @throws IllegalStateException if the spliterator does not report
  16. * a characteristic of {@code SORTED}.
  17. */
  18. default Comparator<? super T> getComparator() {
  19. throw new IllegalStateException();
  20. }
  1. 8个特性值
  1. ORDERED
  2. DISTINCT
  3. SORTED
  4. SIZED
  5. NONNULL
  6. IMMUTABLE
  7. CONCURRENT
  8. SUBSIZED
  9. //更多的是用在并发的时候,指定执行哪些内容。

我们再来看看Spliterator中的8种Characteristic

  1. /**
  2. * Characteristic value signifying that an encounter order is defined for
  3. * elements. If so, this Spliterator guarantees that method
  4. * {@link #trySplit} splits a strict prefix of elements, that method
  5. * {@link #tryAdvance} steps by one element in prefix order, and that
  6. * {@link #forEachRemaining} performs actions in encounter order.
  7. *
  8. * <p>A {@link Collection} has an encounter order if the corresponding
  9. * {@link Collection#iterator} documents an order. If so, the encounter
  10. * order is the same as the documented order. Otherwise, a collection does
  11. * not have an encounter order.
  12. *
  13. * @apiNote Encounter order is guaranteed to be ascending index order for
  14. * any {@link List}. But no order is guaranteed for hash-based collections
  15. * such as {@link HashSet}. Clients of a Spliterator that reports
  16. * {@code ORDERED} are expected to preserve ordering constraints in
  17. * non-commutative parallel computations.
  18. */
  19. public static final int ORDERED = 0x00000010;
  20. /**
  21. * Characteristic value signifying that, for each pair of
  22. * encountered elements {@code x, y}, {@code !x.equals(y)}. This
  23. * applies for example, to a Spliterator based on a {@link Set}.
  24. */
  25. public static final int DISTINCT = 0x00000001;
  26. /**
  27. * Characteristic value signifying that encounter order follows a defined
  28. * sort order. If so, method {@link #getComparator()} returns the associated
  29. * Comparator, or {@code null} if all elements are {@link Comparable} and
  30. * are sorted by their natural ordering.
  31. *
  32. * <p>A Spliterator that reports {@code SORTED} must also report
  33. * {@code ORDERED}.
  34. *
  35. * @apiNote The spliterators for {@code Collection} classes in the JDK that
  36. * implement {@link NavigableSet} or {@link SortedSet} report {@code SORTED}.
  37. */
  38. public static final int SORTED = 0x00000004;
  39. /**
  40. * Characteristic value signifying that the value returned from
  41. * {@code estimateSize()} prior to traversal or splitting represents a
  42. * finite size that, in the absence of structural source modification,
  43. * represents an exact count of the number of elements that would be
  44. * encountered by a complete traversal.
  45. 在执行遍历或者分割之前,由estimateSize返回的值,表示一个有序的大小。
  46. 表示元素的数量的精确的值。
  47. *
  48. * @apiNote Most Spliterators for Collections, that cover all elements of a
  49. * {@code Collection} report this characteristic. Sub-spliterators, such as
  50. * those for {@link HashSet}, that cover a sub-set of elements and
  51. * approximate their reported size do not.
  52. 大部分对于Collections的分割迭代器,一般都会有这个特性值。
  53. */
  54. public static final int SIZED = 0x00000040;
  55. /**
  56. * Characteristic value signifying that the source guarantees that
  57. * encountered elements will not be {@code null}. (This applies,
  58. * for example, to most concurrent collections, queues, and maps.)
  59. */
  60. public static final int NONNULL = 0x00000100;
  61. /**
  62. * Characteristic value signifying that the element source cannot be
  63. * structurally modified; that is, elements cannot be added, replaced, or
  64. * removed, so such changes cannot occur during traversal. A Spliterator
  65. * that does not report {@code IMMUTABLE} or {@code CONCURRENT} is expected
  66. * to have a documented policy (for example throwing
  67. * {@link ConcurrentModificationException}) concerning structural
  68. * interference detected during traversal.
  69. 指定元素的源是不能被修改的,不能被(be added, replaced, or removed)。
  70. 在执行的时候,如果发现被修改,没有返回,则会抛出ConcurrentModificationException并发修改异常。
  71. */
  72. public static final int IMMUTABLE = 0x00000400;
  73. /**
  74. * Characteristic value signifying that the element source may be safely
  75. * concurrently modified (allowing additions, replacements, and/or removals)
  76. * by multiple threads without external synchronization. If so, the
  77. * Spliterator is expected to have a documented policy concerning the impact
  78. * of modifications during traversal.
  79. 表示元素的源能够安全的被并发修改。允许 modified (allowing additions, replacements, and/or removals)。
  80. 不需要外部的同步化的操作。Spliterator的提供了允许被修改的策略。
  81. *
  82. * <p>A top-level Spliterator should not report both {@code CONCURRENT} and
  83. * {@code SIZED}, since the finite size, if known, may change if the source
  84. * is concurrently modified during traversal. Such a Spliterator is
  85. * inconsistent and no guarantees can be made about any computation using
  86. * that Spliterator. Sub-spliterators may report {@code SIZED} if the
  87. * sub-split size is known and additions or removals to the source are not
  88. * reflected when traversing.
  89. 顶层的Spliterator 不应该同时返回:{@code CONCURRENT} and {@code SIZED}。
  90. 因为两者之间存在一定的矛盾性。
  91. 这个的Spliterator 是不一直到,
  92. 得到的Sub-spliterators 可能会返回SIZED。
  93. *
  94. * @apiNote Most concurrent collections maintain a consistency policy
  95. * guaranteeing accuracy with respect to elements present at the point of
  96. * Spliterator construction, but possibly not reflecting subsequent
  97. * additions or removals.
  98. 大多是的这种并发性的集合,都会被维护一定的策略。
  99. :原有的Spliterator ,不会去影响子的Spliterator
  100. */
  101. public static final int CONCURRENT = 0x00001000;
  102. /**
  103. * Characteristic value signifying that all Spliterators resulting from
  104. * {@code trySplit()} will be both {@link #SIZED} and {@link #SUBSIZED}.
  105. * (This means that all child Spliterators, whether direct or indirect, will
  106. * be {@code SIZED}.)
  107. *
  108. * <p>A Spliterator that does not report {@code SIZED} as required by
  109. * {@code SUBSIZED} is inconsistent and no guarantees can be made about any
  110. * computation using that Spliterator.
  111. A Spliterator如果没有返回要求的SIZED。 是没有明确的保证的。
  112. *
  113. * @apiNote Some spliterators, such as the top-level spliterator for an
  114. * approximately balanced binary tree, will report {@code SIZED} but not
  115. * {@code SUBSIZED}, since it is common to know the size of the entire tree
  116. * but not the exact sizes of subtrees.
  117. 有一些Spliterator。如二叉树的整个树的大小,我们得知总的数,但是不知道子的数。
  118. */
  119. public static final int SUBSIZED = 0x00004000;

以上就是关于spliterator的interface所有内容。

Spliterator都支持哪些事情?上面的8个方法。就是具体功能的实现。

OfPrimitive

专门针对于原生的迭代器(int, long, double)

  1. /**
  2. * A Spliterator specialized for primitive values.
  3. *
  4. * @param <T> the type of elements returned by this Spliterator. The
  5. * type must be a wrapper type for a primitive type, such as {@code Integer}
  6. * for the primitive {@code int} type.
  7. * @param <T_CONS> the type of primitive consumer. The type must be a
  8. * primitive specialization of {@link java.util.function.Consumer} for
  9. * {@code T}, such as {@link java.util.function.IntConsumer} for
  10. * {@code Integer}.
  11. * @param <T_SPLITR> the type of primitive Spliterator. The type must be
  12. * a primitive specialization of Spliterator for {@code T}, such as
  13. * {@link Spliterator.OfInt} for {@code Integer}.
  14. *
  15. * @see Spliterator.OfInt
  16. * @see Spliterator.OfLong
  17. * @see Spliterator.OfDouble
  18. * @since 1.8
  19. */
  20. public interface OfPrimitive<T, T_CONS, T_SPLITR extends Spliterator.OfPrimitive<T, T_CONS, T_SPLITR>>
  21. extends Spliterator<T> {
  22. @Override
  23. T_SPLITR trySplit();
  24. /**
  25. * If a remaining element exists, performs the given action on it,
  26. * returning {@code true}; else returns {@code false}. If this
  27. * Spliterator is {@link #ORDERED} the action is performed on the
  28. * next element in encounter order. Exceptions thrown by the
  29. * action are relayed to the caller.
  30. *
  31. * @param action The action
  32. * @return {@code false} if no remaining elements existed
  33. * upon entry to this method, else {@code true}.
  34. * @throws NullPointerException if the specified action is null
  35. */
  36. @SuppressWarnings("overloads")
  37. boolean tryAdvance(T_CONS action);
  38. /**
  39. * Performs the given action for each remaining element, sequentially in
  40. * the current thread, until all elements have been processed or the
  41. * action throws an exception. If this Spliterator is {@link #ORDERED},
  42. * actions are performed in encounter order. Exceptions thrown by the
  43. * action are relayed to the caller.
  44. *
  45. * @implSpec
  46. * The default implementation repeatedly invokes {@link #tryAdvance}
  47. * until it returns {@code false}. It should be overridden whenever
  48. * possible.
  49. *
  50. * @param action The action
  51. * @throws NullPointerException if the specified action is null
  52. */
  53. @SuppressWarnings("overloads")
  54. default void forEachRemaining(T_CONS action) {
  55. do { } while (tryAdvance(action));
  56. }
  57. }

提供了三个特化版本。实现了OfPrimitive接口。

  1. OfInt
  2. OfLong
  3. OfDouble
OfInt
  1. public interface OfInt extends OfPrimitive<Integer, IntConsumer, OfInt> {
  2. @Override
  3. OfInt trySplit();
  4. @Override
  5. boolean tryAdvance(IntConsumer action);
  6. @Override
  7. default void forEachRemaining(IntConsumer action) {
  8. do { } while (tryAdvance(action));
  9. }
  10. /**
  11. * {@inheritDoc}
  12. * @implSpec
  13. * If the action is an instance of {@code IntConsumer} then it is cast
  14. * to {@code IntConsumer} and passed to
  15. * {@link #tryAdvance(java.util.function.IntConsumer)}; otherwise
  16. * the action is adapted to an instance of {@code IntConsumer}, by
  17. * boxing the argument of {@code IntConsumer}, and then passed to
  18. * {@link #tryAdvance(java.util.function.IntConsumer)}.
  19. */
  20. @Override
  21. default boolean tryAdvance(Consumer<? super Integer> action) {
  22. if (action instanceof IntConsumer) {
  23. return tryAdvance((IntConsumer) action);
  24. }
  25. else {
  26. if (Tripwire.ENABLED)
  27. Tripwire.trip(getClass(),
  28. "{0} calling Spliterator.OfInt.tryAdvance((IntConsumer) action::accept)");
  29. return tryAdvance((IntConsumer) action::accept);
  30. }
  31. }
  32. /**
  33. * {@inheritDoc}
  34. * @implSpec
  35. * If the action is an instance of {@code IntConsumer} then it is cast
  36. * to {@code IntConsumer} and passed to
  37. * {@link #forEachRemaining(java.util.function.IntConsumer)}; otherwise
  38. * the action is adapted to an instance of {@code IntConsumer}, by
  39. * boxing the argument of {@code IntConsumer}, and then passed to
  40. * {@link #forEachRemaining(java.util.function.IntConsumer)}.
  41. */
  42. @Override
  43. default void forEachRemaining(Consumer<? super Integer> action) {
  44. if (action instanceof IntConsumer) {
  45. forEachRemaining((IntConsumer) action);
  46. }
  47. else {
  48. if (Tripwire.ENABLED)
  49. Tripwire.trip(getClass(),
  50. "{0} calling Spliterator.OfInt.forEachRemaining((IntConsumer) action::accept)");
  51. forEachRemaining((IntConsumer) action::accept);
  52. }
  53. }
  54. }

问题:要知道Consumer和IntConsumer是没有任何继承关系的话,他们是怎么实现类型转换的呢?

  1. default boolean tryAdvance(Consumer<? super Integer> action) {
  2. if (action instanceof IntConsumer) {
  3. return tryAdvance((IntConsumer) action);
  4. }

如果是纯粹的面向对象的,这种现象是完全不能够存在的。

但是如果是在这函数式编程的情况下,是能够存在的。

原因如下:

  1. java中存在自动装箱和拆箱的操作 (int->Integer)
  2. 强制类型的转换在纯粹的面向对象是一定要存在继承关系的,根本原因还在于函数式编程的lambda上面
  3. lambda的一切信息都是通过上下文推断出来的。(对于同一个lambda表达式,在不同类型中可能推断出来的结果是不同的。在函数式编程中,这种现象是存在的。)

用代码来解释。


JAVA8学习——Stream底层的实现(学习过程)的更多相关文章

  1. JAVA8学习——Stream底层的实现一(学习过程)

    Stream底层的实现 Stream接口实现了 BaseStream 接口,我们先来看看BaseStream的定义 BaseStream BaseStream是所有流的父类接口. 对JavaDoc做一 ...

  2. JAVA8学习——Stream底层的实现二(学习过程)

    继续深入Stream的底层实现过程 2.spliterator() 接上 https://www.cnblogs.com/bigbaby/p/12159495.html 我们这次回到最开始源码分析的地 ...

  3. JAVA8学习——Stream底层的实现三(学习过程)

    Stream的深入(三) 心得:之前学习流,深入了流的底层.但是学的这些东西在平时日常开发的过程中,是根本不会用到的.只是为了更好帮助自己去理解流的底层设施.用起来也更自信,能够确定用的东西非常正确. ...

  4. JAVA8学习——Stream底层的实现四(学习过程)

    Stream的深入(四) 从更高角度去看一下:类与类之间的设计关系 (借助IDEA的图形处理工具 Ctrl+Alt+U). ReferencePipeline的三个实现的子类: Head Statel ...

  5. JAVA8学习——深入浅出Lambda表达式(学习过程)

    JAVA8学习--深入浅出Lambda表达式(学习过程) lambda表达式: 我们为什么要用lambda表达式 在JAVA中,我们无法将函数作为参数传递给一个方法,也无法声明返回一个函数的方法. 在 ...

  6. JAVA8学习——深入Comparator&Collector(学习过程)

    深入Comparator&Collector 从源码深入Comparator Comparator从Java1.2就出来了,但是在1.8的时候,又添加了大量的默认方法. compare() e ...

  7. JAVA8学习——从使用角度深入Stream流(学习过程)

    Stream 流 初识Stream流 简单认识一下Stream:Stream类中的官方介绍: /** * A sequence of elements supporting sequential an ...

  8. Java8学习笔记----Lambda表达式 (转)

    Java8学习笔记----Lambda表达式 天锦 2014-03-24 16:43:30 发表于:ATA之家       本文主要记录自己学习Java8的历程,方便大家一起探讨和自己的备忘.因为本人 ...

  9. Java8学习笔记目录

    Java8学习笔记(一)--Lambda表达式 Java8学习笔记(二)--三个预定义函数接口 Java8学习笔记(三)--方法引入 Java8学习笔记(四)--接口增强 Java8学习笔记(五)-- ...

随机推荐

  1. HZOJ 斐波那契(fibonacci)

    先说一个规律: 如图将每个月出生的兔子的编号写出来,可以发现一只兔子在哪一列他的父亲就是谁. 每列的首项可以通过菲波那契求得. 然后你就可以像我一样通过这个规律打表每个点的父亲,预处理出倍增数组,倍增 ...

  2. phpstorm 左边的文件列表没用了 怎么弄出来

      ALT+1ALT+数字键,是各种工具栏的显示与隐藏快捷键,你可以挨个试一下.

  3. H3C TCP连接的拆除

  4. oracle避免在索引列上使用计算

    WHERE子句中,如果索引列是函数的一部分.优化器将不使用索引而使用全表扫描. 举例: 低效: SELECT … FROM DEPT WHERE SAL * 12 > 25000; 高效: SE ...

  5. Python--day66--Django模板语言关于静态文件路径的灵活写法

    静态文件路径的灵活写法: 正规的讲解: 静态文件相关 {% static %} {% load static %} <img src="{% static "images/h ...

  6. Python--day20--序列化模块

    序列化:转向一个字符串数据类型 序列   ———— 字符串 序列化和反序列化的概念: 序列化三种方法:json pickle shelve json模块:json模块提供了四个方法dumps和load ...

  7. H3C PPP MP简介

  8. iptables一个包过滤防火墙实例

    环境:redhat9 加载了string time等模块 eth0 接外网──ppp0 eth1 接内网──192.168.0.0/24 #!/bin/sh # modprobe ipt_MASQUE ...

  9. H3C 不同匹配顺序导致结果不同

  10. Educational Codeforces Round 65 (Rated for Div. 2) E. Range Deleting(思维+coding)

    传送门 参考资料: [1]:https://blog.csdn.net/weixin_43262291/article/details/90271693 题意: 给你一个包含 n 个数的序列 a,并且 ...