原则:用代码去描述“做什么”而不是“怎么做”
特点:并没有指定操作以什么顺序或者在哪个线程中进行,相比之下的循环就需要指定顺序和线程,因此也丧失优化的机会。
示例:
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方法不会从旧的流中移除元素,而是会生成一个新的流,其中并不包含被过滤掉的元素。流的操作是尽可能的惰性操作。意味着需要其结果时,才会执行。