流式编程的概念(什么是流式编程)

流式编程就是基于JDK8的Stream对于集合一系列的操作的流程定义。
stream是用于对集合迭代器的增强,使之完成能够完成更高效的聚合操作(过滤、排序、统计分组)或者大批量数据操作。此外与stream与lambada表达示结合后编码效率与大大提高,并且可读性更强。
(java8中的stream与lnputStream和OutputStream是完全不同的概念)

问题:如果用SQL其实非常好实现,为什么不在直接关系数据库来实现呢?

对于传统的javaEE项目中数据源比较单一而且集中。
但是对于一些微服务项目而言,比如一个电商项目:订单模块和会员模块可能不是用同一个数据库,也有可能数据库的类型也不同。

Stream产生的背景:

遍历在传统的javaEE项目中数据源比较单一而且集中,像这类的需求都我们可能通过关系数据库中进行获取计算
现在的互联网项目数据源成多样化有:关系数据库、NoSQL、Redis、mongodb、ElasticSearch、Cloud
Server时就需我们从各数据源中汇聚数据并进行统计。 这在Stream出现之前只能过遍历实现非常繁琐。

场景一:跨库join的问题

查询一个店铺的订单信息,需要用到订单表与会员表在传统数据库单一例中可以通过jon 关联轻松实现,但在分布场景中这两张表分别存储在于交易库和会员库两个实例中,join不能用。只能在服务端实现其流程如下:
1.查询订单表数据
2.找出订单中所有会员的ID3.根据会员ID查询会员表信息4.将订单数据与会员数据进行合并
这用传统迭代方法非常繁琐,而这正是stream所擅长的。示例代码如下:

//获取所有会员ID并去重
List<Integer> ids = orders.stream( ).map(o ->
o.getMemberId( ) ) .distinct ( ).collect(collectors.toList( ) ) ;
//合并会员信息至订单信息
orders.stream( ) .forEach(o -> {
Member member = members.stream( ).filter(m -> m.getId() ==
o.getMemberId ( ) ) .findAny ( ).get() ;
o.setMemberName ( member.getName( ) );
}) ;

场景二:N+1问题

N+1 问题是什么?会造成什么影响?应该如何解决? 
 执行一次查询获取N 条主数据后,由于关联引起的执行N次查询从数据
 (例:通过Mysql 查询日志,可以看到查询用户表是一次,因为有四个符合该条件的用户,查询用户表关联的余额表是四次。)
带来了不必要的查询开销 可以通过框架 ORM 自带的with 去解决

Stream执行机制解密?

Stream执行机制其实就是一个流的执行过程

流的执行过程图:

管道里面就是一个一个的逻辑块
不是整个数据源进行传递执行,而是一个一个进行传递执行

流的操作特性

stream不存储数据

stream不改变源数据

stream不可重复使用

java 流式 视频 java流式编程原理_java 流式 视频

流的操作类型

stream所有操作组合在一起即变成了管通,管通中有以下两种操作:中间操作和终值操作

中间操作:(中间节点是懒(惰性的)节点,当终值节点发生才会进行加载(执行))

调用中间操作方法会返回一个新的流。通过连续执行多个操作便就组成了Stream中的执行管道(pipeline)。
需要注意的是这些管道被添加后并不会真正执行,只有等到调用终值操作之后才会执行。

终值操作:最终产生结果的操作为终值操作(一般放在管道的末尾)

在调用该方法后, 将执行之前所有的中间操作,获返同结果,结束对流的使用。
中间操作和终值操作的区别:如果产生方法返回的返回值数据类型是否为Stream类型

Stream中时常用API及场景:

java 流式 视频 java流式编程原理_java_02


(api的相关操作后续更新)