1)流式编程初步
原则:用代码去描述“做什么”而不是“怎么做”
特点:并没有指定操作以什么顺序或者在哪个线程中进行,相比之下的循环就需要指定顺序和线程,因此也丧失优化的机会。
示例:
List<String> words = new ArrayList();
long count = words.stream()
.filter(w -> w.length()>12)
.count();
对应的循环版本:
List<String> words = new ArrayList();、
for(String w : words){
if(w.length()>12){
count++;
}
}
流代码解释:
参考对应循环的代码可以发现,w 是List中的一个对象
word. stream() 方法是生成一个List的流
.filter(w -> w.length()>12) 是过滤出字符串长度大于12的字符串,w是一个List 中的temp 实例对象, ->指向一个过滤条件,满足 -> 之后过滤条件的内容则被过滤出来
.count() 用于计数,记录过滤出来对象的个数
优化版本:
List<String> words = new ArrayList();
long count = words.parallelStream()
.filter(w -> w.length()>12)
.count();
将stream修改为了parallelStream 修改为让流库以并行的方式执行过滤和计数,就通过了多线程来实现效率的提高和优化,也进一步体现了之前说的循环指定了顺序和线程,而流没有的一个优势
三个操作管道:
- 创建一个蕴含数据的流
- 指定条件将原始的流转换为其他流的中间流
- 应用终止操作,从而产生结果,这个操作会强制的执行之前的惰性操作,从此之后这个流将不再使用。(对于上面这段代码来说,流时parallelStream创建的,filter对其转换,cont方法则是终止操作)
流看上去和集合很类似,可以转换和获取数据,但是本质上存在显著的差异:
- 流并不存储其元素。这些元素可能存储在底层的集合中,或者是含需要生成的。
- 流不修改原来的数据源。比如说:filter方法不会从旧的流中移除元素,而是会生成一个新的流,其中并不包含被过滤掉的元素。
- 流的操作是尽可能的惰性操作。意味着需要其结果时,才会执行。