关于 Stream
Java 8 中的 Stream API 是一种全新的处理集合数据的方式,它提供了一种非常便捷的方法来对集合中的元素进行筛选、排序、聚合等操作。
List<Integer> list = Arrays.asList(1,2,3);
// map 将 int 的流,转换为 string 的流,然后对流进行过滤,最后收集到一个 list
List<String> list2 = list.stream().map(x -> x + "123").filter(x -> x.startsWith("11")).collect(Collectors.toList());
特点:
- Stream 是一种延迟计算的集合,它只有在真正需要使用时才会执行计算操作,可以极大地提高效率。
- Stream 可以处理大量数据,其内部使用了多线程的技术,可以自动并行化处理。
- Stream 可以实现非常复杂的操作,比如 filter、map、reduce 等等。
应用场景:
- 数据处理:Stream API 可以用于处理大量的数据,比如从数据库或者文件中读取数据,并对其进行处理。
- 并发编程:Stream API 内部使用了多线程技术,可以实现并发编程,提高程序的执行效率。
- 功能扩展:Stream API 提供了大量的中间操作和终止操作,可以方便地对集合中的元素进行筛选、排序、聚合等操作。
关键特性:
- 流(Stream):Stream 是一个数据流,可以看做是一种集合,但是它并不会存储数据,而是通过函数式编程的方式来对数据进行处理。
- 中间操作:Stream 提供了大量的中间操作,比如 filter、map、distinct、sorted、limit 等等,这些中间操作会返回一个新的 Stream。
- 终止操作:Stream 提供了一些终止操作,比如 forEach、count、reduce、collect 等等,这些操作会触发 Stream 的执行,返回一个结果。
- 并行流:Stream 提供了并行流的功能,可以利用多线程的技术来提高程序的执行效率。可以通过 parallelStream() 方法获取一个并行流。
- 支持函数式编程:Stream API 使用函数式编程的方式来处理数据,可以大大简化程序的编写过程。
对于从 Java 转 C++ 的开发人员来说,这个 API 非常实用。能否在 C++ 中也实现一套类似的 API 呢?
实现思路
Java 的实现分析如下:
list.stream().map(x->x+"123").filter(x->x.startsWith("test")).collect(Collectors.toList());
抽象来看,创建了一系列的 StatelessOp/StateFullOp,通过类似链表的方式串联了起来。最终执行的时候,遍历链表将 StatelessOp/StateFullOp 中用户定义操作,通过 Sink 这个类,一层层 wrapper,最终在收集的时候执行了这个 wrapper。
本质来说就是通过一层一层的回调函数的方式将多个操作串联了起来。那么 C++ 也可以通过回调函数的方式直接实现一个简易的类似 Java 中 Stream 的 API。
也可以通过生产消费者模型来解释,本质都是一样的:有 AB 两个模块,A 负责生产数据,B 负责消费数据,B 不关心 A 怎么生产,A 不关心 B 怎么消费。可能需要先过滤,转换,或者聚合什么的,这种情况下,传统的做法就是在 A 提供一个接口,注册一个回调函数,B 负责调用,当 A 生产出数据的时候,调用 B 注册的回调函数进行消费。
思路打开,如果有 ABCD... N 个模块呢,一级级注册回调函数,将这些回调函数级联起来,是不是就很像 Stream 的 API 呢?而且由于都是回调函数,天生是懒加载的,或者说天生支持反应式编程中的背压机制,就是说会根据消费者的消费速度去生产数据。

