java读流怎么从中间开始_Java Stream 的中间操作(二)

上篇Stream Head的构建(一)我们用Collection.stream构建了源头,长相如下图

0dfa4bb1888e

stream_source_head.png

此篇以集合为源,看一个简单的流的中间操作。

List names = Arrays.asList("one", "two", "three", "four");

Stream stream = names.stream()

//具体Lambda表达式或方法引用先不用管

.filter(s -> s.length() > 2)

.map(String::toUpperCase);

在上图中把源头设为stream0,接下来filter(...)在stream0上操作,返回一个中间流StatelessOp,和Head一样也是ReferencePipeline子类

ReferencePipeline.java

public final Stream filter(Predicate super P_OUT> predicate) {

Objects.requireNonNull(predicate);

//这里this就是stream0

return new StatelessOp(this, StreamShape.REFERENCE,

StreamOpFlag.NOT_SIZED) {

@Override

public Sink opWrapSink(int flags, Sink sink) {

//这里实现了重要的抽象方法opWrapSink,以一个Sink作为参数,又返回一个Sink,先忽略

...

}

};

}

我们只看StatelessOp的构造方法

public StatelessOp(AbstractPipeline, E_IN, ?> upstream,inputShape,opFlags) {

super(upstream, opFlags);

}

和Head一样也是调用的AbstractPipeline构造方法,只不过Head调用的是专门构造源头的,StatelessOp或StatefulOp调用的是专门构造中间管道的。

AbstractPipeline.java

//previousStage就是stream0

AbstractPipeline(AbstractPipeline, E_IN, ?> previousStage, int opFlags) {

if (previousStage.linkedOrConsumed)

throw new IllegalStateException(MSG_STREAM_LINKED);

previousStage.linkedOrConsumed = true;

//上个stream的next指向自己

previousStage.nextStage = this;

//自己的previous指向上个 stream

this.previousStage = previousStage;

this.sourceOrOpFlags = opFlags & StreamOpFlag.OP_MASK;

this.combinedFlags = StreamOpFlag.combineOpFlags(opFlags, previousStage.combinedFlags);

this.sourceStage = previousStage.sourceStage;

if (opIsStateful())

sourceStage.sourceAnyStateful = true;

this.depth = previousStage.depth + 1;

}

filter方法调用完后,如下图

0dfa4bb1888e

stream_filter.png

再看map,在stream1上操作,和filter雷同

ReferencePipeline.java

public final Stream map(Function super P_OUT, ? extends R> mapper) {

Objects.requireNonNull(mapper);

return new StatelessOp(this, StreamShape.REFERENCE,

StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {

@Override

public Sink opWrapSink(int flags, Sink sink) {

...同上

}

};

}

0dfa4bb1888e

stream_map.png

这个过程其实就是一个双向链表的构建,但每个中间流都含有源头的引用,为啥呢?图片来自

https://cloud.tencent.com/developer/article/1333533

0dfa4bb1888e

stream_structure.png

还有些中间操作,如sorted,flatMap都类似,暂且不表。到此并没有实际的计算,接下来再看Java Strem 的终止操作(三)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值