Stream操作整理

Stream操作整理

Stream 的特性可以归纳为:

  • 不是数据结构

  • 它没有内部存储,它只是用操作管道从 source(数据结构、数组、generator function、IO channel)抓取数据。

  • 它也绝不修改自己所封装的底层数据结构的数据。例如 Stream 的 filter 操作会产生一个不包含被过滤元素的新 Stream,而不是从 source 删除那些元素。

  • 所有 Stream 的操作必须以 lambda 表达式为参数

  • 不支持索引访问

  • 你可以请求第一个元素,但无法请求第二个,第三个,或最后一个。不过请参阅下一项。

  • 很容易生成数组或者 List

  • 惰性化

  • 很多 Stream 操作是向后延迟的,一直到它弄清楚了最后需要多少数据才会开始。

  • Intermediate 操作永远是惰性化的。

  • 并行能力

  • 当一个 Stream 是并行化的,就不需要再写多线程代码,所有对它的操作会自动并行进行的。

  • 可以是无限的

  • 集合有固定大小,Stream 则不必。limit(n) 和 findFirst() 这类的 short-circuiting 操作可以对无限的 Stream 进行运算并很快完成。

Intermediate

一个流可以后面跟随零个或多个 intermediate 操作。其目的主要是打开流,做出某种程度的数据映射/过滤,然后返回一个新的流,交给下一个操作使用。这类操作都是惰性化的(lazy),就是说,仅仅调用到这类方法,并没有真正开始流的遍历。

map

1:1映射

flatMap

1:n映射

filter

distinct

sorted

对元素进行排序

比数组排序强的地方在于可以在经过map、limit。distinct等操作减少待排序元素数量之后再进行排序,也就是说要注意sorted和上述操作的执行顺序,同时这也限制了sorted能满足的需求,即先过滤后排序

时间成本nlog(n)

peek

forEach的非terminal版本

limit

返回前面n个元素

对于parallel stream而言,如果其元素有序(即在limit执行前执行sorted),那么使用limit成本会高,所以尽量不要在parallel stream使用limit或者取消元素间的顺序(不要在limit前使用sorted)

skip

丢掉前面n个元素

parallel

unordered

Terminal

一个流只能有一个 terminal 操作,当这个操作执行后,流就被使用“光”了,无法再被操作。所以这必定是流的最后一个操作。Terminal 操作的执行,才会真正开始流的遍历,并且会生成一个结果,或者一个 side effect。

forEach

串行的foreach和传统的for循环几乎无性能差异

不能修改本地变量值

不能使用break/return提前结束循环

forEachOrdered

toArray

reduce

作用是吧stream元素组合起来

其提供一个起始值,然后依照运算规则和stream的第1个、第2个...第n个元素组合

当无起始值时,则把stream的第1、2个元素组合起来,返回optional

典型的操作:

求和

求最值

求平均值

字符串拼接

collect

min

时间成本O(n)

max

时间成本O(n)

count

anyMatch

allMatch

noneMatch

findFirst

返回的是optional类型

findAny

iterator

必须有limit这类的操作限制大小,和reduce很像,接受一个seed和一个f(x),

seed成为stream第一个元素,然后f(seed)是第二个,f(f(seed))是第三个

Short-circuiting

对于一个 intermediate 操作,如果它接受的是一个无限大(infinite/unbounded)的 Stream,但返回一个有限的新 Stream。

对于一个 terminal 操作,如果它接受的是一个无限大的 Stream,但能在有限的时间计算出结果。

anyMatch

allMatch

findFirst

findAny

limit

collectors

辅助进行各类有用的reduce操作

partitioningBy

groupingBy

你可能感兴趣的:(Stream操作整理)