Stream的深入(三)
心得:之前学习流,深入了流的底层。但是学的这些东西在平时日常开发的过程中,是根本不会用到的。只是为了更好帮助自己去理解流的底层设施。用起来也更自信,能够确定用的东西非常正确。
专注技术:这种纯技术的这种环境。
而不是说:专注业务开发了5年,技术没有长进。
这位张龙老师给讲课的方式,就是学习一门新技术的过程。如果觉得这种方式学习起来很有效的话。可以使用这种方式去学习一门新的技术。
lambda表达式和匿名内部类完全不同之前虽然学了流了,但是还不太够。我们还缺少了一个能够把一个流从头到尾的执行过程给用起来的过程。
接下来会完成这个目的
用程序入门。
public class LambdaTest { //内部类和lambda表达式到底有什么关系 Runnable r1 = () -> System.out.println(this); //匿名内部类 - 标识我生成了一个Runnable的实例 . 是一个类 Runnable r2 = new Runnable() { @Override public void run() { System.out.println(this); } }; public static void main(String[] args) { LambdaTest lambdaTest = new LambdaTest(); Thread t1 = new Thread(lambdaTest.r1); t1.start(); System.out.println("-------------"); Thread t2 = new Thread(lambdaTest.r2); t2.start(); //请问,输出结果一样吗? } }运行结果:
------------- com.dawa.jdk8.LambdaTest@59a30351 (lambda表达式的结果) com.dawa.jdk8.LambdaTest$1@2831008d (匿名内部类的结果) Process finished with exit code 0LambdaTest$1, 这个1就是匿名内部类的类名。 (匿名内部类的名字)
经过对比,虽然说 lambda是匿名内部类的不同实现,但是 他们两个是完全一样的。原理不同。
结论:
匿名内部类会开辟一个新的作用域
lambda是不会开辟新的作用域的
这里普及这个知识点,是为了以后在Debug的时候会发现 匿名内部类和lambda表达式的类名不同、
系统的去走一遍stream的执行流程
public class StreamTest3 { public static void main(String[] args) { List<String> list = Arrays.asList("hello", "world", "welcome"); list.stream().map(item->item+"_abc").forEach(System.out::println); } }map()实现
返回值为StatelessOp
@Override @SuppressWarnings("unchecked") public final <R> Stream<R> map(Function<? super P_OUT, ? extends R> mapper) { Objects.requireNonNull(mapper); return new StatelessOp<P_OUT, R>(this, StreamShape.REFERENCE, StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) { @Override Sink<P_OUT> opWrapSink(int flags, Sink<R> sink) { return new Sink.ChainedReference<P_OUT, R>(sink) { @Override public void accept(P_OUT u) { downstream.accept(mapper.apply(u)); } }; } }; } //StatelessOp类的定义和构造方法 /** * Base class for a stateless intermediate stage of a Stream. * * @param <E_IN> type of elements in the upstream source * @param <E_OUT> type of elements in produced by this stage * @since 1.8 */ abstract static class StatelessOp<E_IN, E_OUT> extends ReferencePipeline<E_IN, E_OUT> { /** * Construct a new Stream by appending a stateless intermediate * operation to an existing stream. * * @param upstream The upstream pipeline stage * @param inputShape The stream shape for the upstream pipeline stage * @param opFlags Operation flags for the new stage */ StatelessOp(AbstractPipeline<?, E_IN, ?> upstream, StreamShape inputShape, int opFlags) { super(upstream, opFlags); assert upstream.getOutputShape() == inputShape; } @Override final boolean opIsStateful() { return false; } }StatelessOp继承ReferencePipeline,而ReferencePipeline实现了Stream.
所以map方法返回new StatelessOp<P_OUT, R>就等于返回了一个Stream
返回的是继承了StatelessOp的子类的对象。完成了上游和下游流的互通.
Reference Pipeline 无非就是一个双向链表
操作包装:map()方法中的 opWrapSink()的ChainedReference,实现了流的包装操作。把剩下的流给warp到一起
然后就一个元素,同时经过了剩下的方法操作。
@Override Sink<P_OUT> opWrapSink(int flags, Sink<R> sink) { return new Sink.ChainedReference<P_OUT, R>(sink) { @Override public void accept(P_OUT u) { downstream.accept(mapper.apply(u)); } }; } Sink 类 * <p>A sink may be in one of two states: an initial state and an active state. * It starts out in the initial state; the {@code begin()} method transitions * it to the active state, and the {@code end()} method transitions it back into * the initial state, where it can be re-used. Data-accepting methods (such as * {@code accept()} are only valid in the active state. *ChainedReference()链接引用
/** * Abstract {@code Sink} implementation for creating chains of * sinks. The {@code begin}, {@code end}, and * {@code cancellationRequested} methods are wired to chain to the * downstream {@code Sink}. This implementation takes a downstream * {@code Sink} of unknown input shape and produces a {@code Sink<T>}. The * implementation of the {@code accept()} method must call the correct * {@code accept()} method on the downstream {@code Sink}. */ static abstract class ChainedReference<T, E_OUT> implements Sink<T> { protected final Sink<? super E_OUT> downstream; public ChainedReference(Sink<? super E_OUT> downstream) { this.downstream = Objects.requireNonNull(downstream); } @Override public void begin(long size) { downstream.begin(size); } @Override public void end() { downstream.end(); } @Override public boolean cancellationRequested() { return downstream.cancellationRequested(); } }Sink类中的end(),和 begin()方法,切换两种状态:1.初始状态 2.激活状态
每一次accept()方法执行之前,需要调用Sink中的begin()方法,进入激活状态,执行完毕之后调用end()方法,进入初始状态。
涉及设计模式:模板方法模式。
opWrapSink() 的上级实现: