接受了一个Sink对象,这个对象接受了操作的结果,并且返回了一个Sink,还会执行这个操作,并将这个结果传递给所提供的sink。 *(输入参数才是带结果的sinK)
正是因为这种操作,才能将sink给包装起来。
流的特性:惰性求值和延迟求值。
map()方法,包括其他的peek(),filter()等等中间操作的这些方法。只是完成了返回了一个StatelessOp对象。
所以中间操作返回一个终止对象可能执行的StatelessOp,没有终止操作,所以流不会被处理。
那么终止操作。我们要去追一下了。
拿代码中写的 forEach()方法开始去追
// Terminal operations from Stream @Override public void forEach(Consumer<? super P_OUT> action) { evaluate(ForEachOps.makeRef(action, false)); }这是调用了makeRef()方法.方法在ForEachOps类中.
先看ForEachOps类的javadoc
/** * Factory for creating instances of {@code TerminalOp} that perform an * action for every element of a stream. Supported variants include unordered * traversal (elements are provided to the {@code Consumer} as soon as they are * available), and ordered traversal (elements are provided to the * {@code Consumer} in encounter order.) 这是一个工厂,用来创建 TerminalOp 对象,(终止操作。)这个对象会对每一个元素执行一个动作。 所支持的变化包括:无序的遍历,有序的遍历(按照所提供的的顺序来遍历)。 * * <p>Elements are provided to the {@code Consumer} on whatever thread and * whatever order they become available. For ordered traversals, it is * guaranteed that processing an element <em>happens-before</em> processing * subsequent elements in the encounter order. 元素被提供被一个任何可用的Consumer队形。 处理一个元素,一定是发生在 另外一件事之前 (happens-before)。 也就事 先遇到的元素先处理,后遇到的元素后处理。 * * <p>Exceptions occurring as a result of sending an element to the * {@code Consumer} will be relayed to the caller and traversal will be * prematurely terminated. 提供了大量的 静态方法。 * * @since 1.8 */ final class ForEachOps { }如makeRef()
/** * Constructs a {@code TerminalOp} that perform an action for every element * of a stream. * * @param action the {@code Consumer} that receives all elements of a * stream * @param ordered whether an ordered traversal is requested * @param <T> the type of the stream elements * @return the {@code TerminalOp} instance */ public static <T> TerminalOp<T, Void> makeRef(Consumer<? super T> action, boolean ordered) { Objects.requireNonNull(action); return new ForEachOp.OfRef<>(action, ordered); }TerminalOp说明