java stream API初探(二):为了高效

来源:互联网 发布:连环杀人知乎 编辑:程序博客网 时间:2024/05/18 12:33

在尝试使用stream api后,如果不了解stream api背后的优化机制,肯定会产生担心,觉得它中看不中用。本文就是为了消解这类担忧而写。
好的api不仅让你用得方便,还要让你用的放心。stream api已经进行了效率上的优化,能满足多数情况下所需的高效。
比如当你遍历序列,搜寻特定值时,希望一旦得到结果则立即返回,而不是遍历全部值。有时,判断元素满足特定条件的过程十分复杂,更应该尽可能减少判断次数。注重程序效率的你,一定会在普通的循环中进行条件判断加以剪枝,对这些情况进行优化。也许在你看来,具体场景下的优化措施各异,而stream api 通过关注其中的公共点,不露痕迹地完成繁琐的优化任务。

我们先通过一个具体的例子,说明stream api如何进行优化,顺带引入它的一些概念。

下面的例子,是搜寻许多学生中满足特定条件的学生。

class Student{    private int age;    boolean fun(){        //极为耗时的操作,例如查询数据库等        //进行一些判断,返回布尔值    }    int age(){        return age;    }}
List<Student> students = new ArrayList<Student>();//填充students,假设students中包含100万个student对象students.stream()        .filter(Student::fun)        .map(stu->return stu.age())        .findAny();//注意这里的findAny

在上面的代码中,目的是为了找出能使fun()返回true的Student对象,并返回这个student的age属性。假设Student::fun方法是极为耗时的,并且序列包含海量对象。那么这种时候,我们要避免处理不必要的元素,找到满足条件的学生就执行后续操作。
考察程序执行过程,一种显而易见的处理方式是,程序先对所有对象进行了filter,再取出过滤后的student对象的age属性,最后选择其中任意一个值。
但是这个过程存在极大浪费,更加合理的过程应该是,在遍历的同时,每访问一个student对象,就执行fun方法,如果返回true,则取其age属性值。这样就可能减少fun的执行次数,对元素的访问次数。stream api正是这样做的。

那么它是如何实现这点的呢?通过了解两个概念来回答这个问题。

1.intermediate and terminal operation
中间操作与终止操作。
前面一篇文章已经提到过stream中的pipeline,意指多个操作的组合。一个pipeline中可以有任意个中间操作,但最后的必须是终止操作,且只有一个终止操作。这并非语法上的要求。但假如一个pineline只包含中间操作,那么它没有任何实际效果,即任何操作都没有执行。只有当终止操作存在时,操作才能真正执行。
举例说明:

//符合语法,但无任何意义students.stream().filter(Student::fun());

上面代码中的fun方法,一次都不会执行。你可以在fun中加入输出语句进行验证。这是因为,filter是一个中间操作(intermediate operation)。要想使这句话产生实际效果,末尾需要加一个终止操作,例如findAny,max。
在stream api文档中,会明确指出某个操作属于中间操作或终止操作。如果你把这些操作全部了解一遍,你会发现它们的返回值或是含义是有规律可循的。中间操作只能返回一个Stream对象,含义是对原有stream进行某种映射得到新的stream;终止操作往往返回一个具体对象,含义是从stream中推出某个结果。

2.lazy stream
一个pineline的执行过程,是每当从原stream中取出一个元素,就令它通过所有中间操作,直到终止操作。如果终止操作的执行,需要其它元素参与,如max,min(需要和其余元素比较),则进行等待。如果终止操作的执行不需要其他元素的参与,如findAny,则直接返回结果。

回到对效率问题的解答。在上面示例中,从stream中取出一个元素时,首先经过filter,map,最终到达findAny。因为findAny的执行不需要其它元素的参与,所以就直接得到结果,避免了多余的访问。

以上是stream api对pipeline执行过程的设计。除此之外,我们常用的优化方法是,将串行变为并行。而stream api的底层实现也考虑到了这一点,这是你从表面完全看不到的。

结语:
当这些设计呈现在我面前时,除了解除我对效率的担忧,还让我感到抽象的力量。从低层角度看,每个问题的优化策略都是不同的,但是stream api可以通过提取其中的共同点,解决其中的关键问题,在高层角度解决了大部分情况的优化问题。

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 ps图层解锁不了怎么办 沈腾结婚马丽怎么办 延长甲没有纸托怎么办 高考第一志愿没录取怎么办 电子画颜料干了怎么办 数字画颜料干了怎么办 彩砂纸画不好了怎么办 宝宝吃了油画棒怎么办 2岁宝宝不爱刷牙怎么办 两岁宝宝不刷牙怎么办 1岁宝宝不爱刷牙怎么办 3岁宝宝不肯刷牙怎么办 20岁没学历迷茫怎么办 四岁了不长头发怎么办 17岁掉头发严重怎么办 头发很油,又少怎么办 25岁头发变稀怎么办 宝宝头发少又黄怎么办 头旋附近头发少怎么办 25岁掉头发严重怎么办 2岁宝宝头发稀少怎么办 掉头发很厉害怎么办吧 头发点的很厉害怎么办 为什么掉头发很厉害怎么办 产后2年脱发严重怎么办 产妇掉头发很厉害怎么办 头发掉了怎么办小妙招 头顶头发掉的厉害怎么办 20岁头发有些少怎么办 头痒头发掉厉害怎么办 头油头痒掉头发怎么办 头发痒掉发严重怎么办 宝宝的脸皴了怎么办 宝宝冬天脸皴了怎么办 白衬衣领子变黄怎么办 白衬衣领子烂了怎么办 玩手机眼睛红了怎么办 吃了发芽的土豆怎么办 散尾竹叶子发黄怎么办 吃了一朵长春花怎么办 3d模型打开缓慢怎么办