各大编程语言/技术/框架官网挂出黑人种族运动
|
上述代码看似复杂,其实逻辑很简单,就是将回调函数mapper包装到一个Sink当中。由于Stream.map()是一个无状态的中间操作,所以map()方法返回了一个StatelessOp内部类对象(一个新的Stream),调用这个新Stream的opWripSink()方法将得到一个包装了当前回调函数的Sink。
再来看一个复杂一点的例子。Stream.sorted()方法将对Stream中的元素进行排序,显然这是一个有状态的中间操作,因为读取所有元素之前是没法得到最终顺序的。抛开模板代码直接进入问题本质,sorted()方法是如何将操作封装成Sink的呢?sorted()一种可能封装的Sink代码如下: 有了上面的协议,相邻Stage之间调用就很方便了,每个Stage都会将自己的操作封装到一个Sink里,前一个Stage只需调用后一个Stage的accept()方法即可,并不需要知道其内部是如何处理的。当然对于有状态的操作,Sink的begin()和end()方法也是必须实现的。 比如Stream.sorted()是一个有状态的中间操作,其对应的Sink.begin()方法可能创建一个乘放结果的容器,而accept()方法负责将元素添加到该容器,最后end()负责对容器进行排序。对于短路操作,Sink.cancellationRequested()也是必须实现的,比如Stream.findFirst()是短路操作,只要找到一个元素,cancellationRequested()就应该返回true,以便调用者尽快结束查找。Sink的四个接口方法常常相互协作,共同完成计算任务。实际上Stream API内部实现的的本质,就是如何重载Sink的这四个接口方法。(Java知音公众号回复“面试题聚合”,送你一份Java面试题宝典)
有了Sink对操作的包装,Stage之间的调用问题就解决了,执行时只需要从流水线的head开始对数据源依次调用每个Stage对应的Sink.{begin(), accept(), cancellationRequested(), end()}方法就可以了。一种可能的Sink.accept()方法流程是这样的 图中通过Collection.stream()方法得到Head也就是stage0,紧接着调用一系列的中间操作,不断产生新的Stream。这些Stream对象以双向链表的形式组织在一起,构成整个流水线,由于每个Stage都记录了前一个Stage和本次的操作以及回调函数,依靠这种结构就能建立起对数据源的所有操作。这就是Stream记录操作的方式。 操作如何叠加 以上只是解决了操作记录的问题,要想让流水线起到应有的作用我们需要一种将所有操作叠加到一起的方案。你可能会觉得这很简单,只需要从流水线的head开始依次执行每一步的操作(包括回调函数)就行了。 这听起来似乎是可行的,但是你忽略了前面的Stage并不知道后面Stage到底执行了哪种操作,以及回调函数是哪种形式。换句话说,只有当前Stage本身才知道该如何执行自己包含的动作。这就需要有某种协议来协调相邻Stage之间的调用关系。
这种协议由Sink接口完成,Sink接口包含的方法如下表所示: 城市必须致力于大数据战略,以实现可持续发展的智慧。利用生成的数据量,不仅可以更好地了解城市的运作方式及其居民的行为,而且还可以消除各种参与者和运营商之间的障碍,并创建更适合新用途的新服务。 但是仅生成数据本身是不够的。计划者和组织必须访问数据,并且数据必须准确且值得信赖。话虽这么说,部署的数字平台需要能够大规模收集数据并创建一个单一的信任点,在此可以对数据进行质量检验、 分类和保护。不仅如此,他们还必须支持集成、共享、发现和治理,以便计划者可以跟踪和监视其数据。数据将成为最有价值的商品之一,如果有效地设计一个智慧城市,将会生成大量的丰富且适用的数据,但这仅对具有数据完整性的计划者有益。 面对城市转型对城市资源可能带来的潜在问题,我们迫切需要寻求明智的解决方案。在城市规划中确保强大的数据策略并充分利用边缘优势是有助于减轻过渡带来的各种影响的有效方法。
从数字时代铺平道路的其他城市中汲取灵感,我们需要部署智能解决方案,以消除人类活动对环境的影响并有效管理不断增长的人口资源。数据完整性、数据速度和数据信任是所有基础,这些基础使边缘生成的数据可以支持和发展未来的智慧城市。 (编辑:广元站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |

