1. 水在前面
接着上周的Lambda表达式,这周学习了流。说实话作为工具来讲,这玩意好像挺强大的,倒是真要掌握这工具貌似要记住不少东西,年纪大了不想背书的可以看看这篇水文,等到用的时候再根据具体的使用找度娘。(题外话,现在大家码的时候一般是用的什么搜索引擎?)
2. 关于教材
还是推荐上周这本《JAVA 8 实战》Raoul-Gabriel Urma,Mario Fusco 著 (pdf版 wx号:zhenyeli86 添加好友请说明技术交流,5毛党)。其实不是很想推荐这本书,这本书对并行流这部分的描述感觉不是很到位(当然也有可能是我的理解能力低 -_- )。但是这周有点懒没对比其他的书籍了,就先这样吧。
3. 学习记录
以前对于流的认知stream的认知很局限,认为只是用在网络编程里的通讯工具。经过一周的学习,发现流还是挺有用的,起码是挺好用的。它为我们提供了一种可以简洁、优雅地处理集合集合的工具。
3.1. 流是什么
流是JAVA8 提供的API接口,是一种处理集合的工具,这里的集合是一个宽泛的概念,包括字符串、数组、list、set等等有序或无序的元素集合。
可以通俗的认为,stream为集合提供了内部迭代,就是说它帮我们实现迭代,而不需要我们写foreach之类的东西了。
好吧,水成这样,我自己都不好意思。。。不过这里先稍微有个概念,后面我再说说流这里面体现的设计模式思想。
3.2. 流操作
整个stream的操作说复杂也不复杂,总结起来也就两大类:中间操作和终端操作。
- 中间操作就是把输入的是流,输出的也是流。
- 终端操作就是把输入流计算、转换、规约成一个结果。
说到这里提一下集合跟流的那点破事,上面说到流是一种处理集合的工具,流通通过把集合转换成独特数据结构stream,然后用自身提供的函数工具来完成对集合的处理。流从内部帮我们完成了遍历集合的工作,但是流经过流操作以后数据是不能逆的。怎么说呢?集合foreach只是遍历,不会破坏(当然你要破坏也行)集合,但是经过流操作以后就把数据破坏了。你要重新来就只能把集合重新转成流了。总而言之,流只能遍历一次!
3.3. 使用流
流的使用也简单,我们看一段代码,没有什么语法可言,就是简单的调用函数而已。
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class Demo {
public static void main(String[] args) {
// TODO Auto-generated method stub
List<String> names = Arrays.asList("Peter", "John", "Rose");
//主要看这里就行了
List<Integer> longNames = names.stream() //list 转换成stream
.map(String::length) // 中间操作
.collect(Collectors.toList()); //终端操作
for(Integer len : longNames){
System.out.print(len.toString() + " ");
}
}
}
到这里,基本就清楚了该怎么使用stream了,后面只要大家在使用的时候根据自己的需求去选择相应的中间操作API和终端操作API就好了。是不是很简单!
3.4. 流背后的设计思想
函数式编程的思想就不说了(其实我也没弄清楚函数式编程的思想是啥。。。),这里准备水一下“Builder模式(建造者模式)”。
其实一开始看stream的时候,感觉有点像职责链模式。但是职责链要求数据沿着链条往下走,并且职责链模式是行为模式,跟stream貌似有点不搭。想了几天后来在回看《JAVA8实战》的时候偶然看到原来书上写得好明白。
立刻去复习一遍建造者模式:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
意思确实是有那么点意思!就是你要创建一个复杂的对象,这个对象需要好几个步骤来完成,但是不同的实现可能需要不同的步骤来组合。对于流来说就调用不同的中间操作,最后用中间操作来结束!
嗯,学习了新知识有复习了老东西,挺好!以后想到建造者模式,就想起stream,肯定不会忘记。
3.5. 关于并行流
本来想详细学习一下并行流的内容,但是书上写的有点不到位(反正我看不深入),这里就先粗略记录,后续找机会专门学习java的并行编程再详细水。
通俗的水,并行流就是通过不断拆分流中的数据(或者说是任务),一直到规模足够小,然后把这些任务分配到多核CPU的核上来进行并行处理,最后再把结果合并从而提高运行效率。
这是分治算法思想的应用,核心在于拆分(分治)多少个任务以及是否需要用并行运算(有时候直接单核流水才是最佳实践)的判断。其中有个技术很有意思:work steal(工作窃取)。就是把等待执行的任务队列中的任务,调整分配到空闲的任务队列中,以提高并行效率(负载均衡思想)。当然,我们可以使用java给我们提供的拆分方式,也可以自定义拆分方式以达到最佳效果,毕竟高手在民间啊。
4. 水在最后
今天岳父大人生日,要去请他老人家吃饭,只能先水这么多了。本周的学习确实在并行流方面看的不够深入,先留个引子,有机会专门看一看JAVA并发编程相关的内容来填上缺口。
因为工作的关系,接下来主要从事数据治理相关的东西,关于JAVA的学习先暂停一下了,这段时间看的东西虽然不多,但是发现其实JAVA还是很博大精深的,以前是真的思维局限了。。。