Sink

说明文档

  • Consumer 的扩展,用于在流管道的各个阶段处理值,并且提供了额外的方法去管理大小信息、控制流程等
    • 在首次调用 Sink 的 accept() 方法之前,必须首先调用 begin() 方法去通知其数据即将过来(视情况还会通知 Sink 有多少数据即将过来),在所有数据发送过来后,必须调用 end() 方法。
      • begin 与 end 之间调用 accept
    • 在调用了 end() 方法后,就不应该再调用 accept() 方法,除非再次调用 begin() 方法
    • Sink 还提供了一种机制,sink 可以发出不希望再接收更多数据的信号
  • 一个 Sink 可以处于下述两个状态之一
    • 初始状态 与 激活状态
    • 由初始状态起步
      • begin() 方法会将其准换为激活状态
      • end() 方法又会将其转换会初始状态
      • 因此它可以被重用
    • 数据接受方法(如 accept())只在激活状态下有效
  • apiNote
  • 一个流管道包括一个源、零个或多个中间阶段(比如过滤filter或映射map),和一个终止阶段(比如 reduction 或 for-each)
  • 一个 Sink 实例用于表示当前管道中的每一个阶段,无论阶段接收的是 objects、longs,或doubles
    • 对于 accept(Object)、accept(int) 等,Sink 拥有一个入口点,因此对于各个原生特化的情况我们不需要特殊的接口
      • 这个管道的入口点就是过滤阶段的 Sink,用于将一些元素发送到下游,进入映射阶段的 Sink,进而将将整型值往下游的汇聚阶段的 Sink 发送(以文档中的例子为例)
    • 关联某个给定阶段的 Sink 的实现,期望知道下一阶段的数据类型,并且在其下游的 Sink 中调用正确 accept 方法
    • 类似的,每个阶段必须使用与数据的类型相符的 accept 方法
  • 特殊子类,如 Sink.OfInt,针对特定原生类型,重写 accept(Object) 方法,实现调用对应的 Consumer,并对对应的原生类型的 accept 方法进行再抽象化
  • 连接的子类型,如 ChainedInt
    • 不仅实现了 Sink.OfInt
    • 还维护一个“下游”字段,用于表示下游的 Sink
    • 同时实现 begin、end 方法,以及 cancellationRequested 方法,用于将计算结果传递到下游的 Sink
  • 大部分的中间操作的实现都会使用这个链接包装

ChainedReference

说明文档

  • 抽象的 Sink 的实现,用于构造 sink 的链
  • begin、end、cancellationRequested 方法用于链接到下游的 Sink
  • 此实现携带一个输入类型未知的下游的 Sink,并构造一个指定类型的 Sink<T>
  • accept 方法的实现必须调用下游 Sink 的正确的 accept 方法

构造方法及实现

 

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();
}

 

posted @ 2019-09-17 23:24  飞蛇在水  阅读(1541)  评论(0编辑  收藏  举报