理解

流提供了一种让我们可以在比集合更高的概念级别上指定计算的数据视图。通过使用流,我们可以说明想要完成什么任务,而不是说明如何去实现它。我们将操作的调度留给具体实现去解决
假设我们想要计算某个属性的平均值,那么我们就可以指定数据源和该属性,然后,流库就可以对计算进行优化

从迭代到流

  1. words.stream().filter(w->w.length() > 12).count()

1 仅将stream修改为parallelStream就可以让流库以并行方式来执行过滤和计数
2 流遵循了“做什么而非怎么做”的原则
3 流并不存储其元素。这些元素可能存储在底层的集合中,或者是按需生成的
流的操作不会修改其数据源
流的操作是尽可能惰性执行的。这意味着直至需要其结果时,操作才会执行,
甚至可以操作无限流
4 流的操作包含3步, 创建 转换 终止

创建

1 可以用Collection接口的stream方法将任何集合转换为一个流
2 对于数组 可以用静态的 Stream.of 方法 转换为 流
3 Array.stream(array,from,to) 可以从数组的某一段 组成流
4 Stream.empty() 可以创建 空的流,Stream.generate() 可以创建无限流

filter map 和 flatMap方法

1 流的转换会产生 一个新的流,
2 filter 用于过滤 通过一个 Predicate
3 map 用于转换流 元素
4 flatMap , 假设容器内一个元素 就会转换为 带有多个元素的流,那么flatMap 可以将 流的流转化为 一个 流

抽取子流和连接流

1 limit(n) 会返回一个 前n项元素 组成的 流,用于裁剪无限流 很有用
2 可以用Stream的静态concat方法 将两个流连起来

其他的流转换

1 distinct 用来去除重复元素
2 sorted 可以排序 comparable对象 ,或者额外传入 comparator

约简

1 约简是一种终结操作,将流 转化为 非流值
2 count 获取流的长度, min 获取最小值, max 获取最大值 (前提是comparable对象 或者传入 comparator)
返回的都是 Optional类型
3 findFirst 第一个值, findAny 任意值 和filter搭配 很有效
4 allMatch 和 noneMatch 方法 接收一个Predicate

Optional类型

1 Optional对象是一种包装器对象,要么包装了类型T的对象,要么没有包装任何对象,可以防止NPE
2 Optional 对象 可以调用 orElse(v) orElseGet(()->xxx),orElseThrow(E e)在没有包装任何对象的时候进行对应的操作
3 ifPresent(v-> process) 只有包装了对象的时候 才处理
4 直接get不安全,get方法会在Optional值存在的情况下获得其中包装的元素,或者在不存在的情况下抛出一个NoSuchElementException对象
5 可以通过Optional.of 和 Optional.empty 创建 Optional对象
Optional.ofNullable(obj)方法 如果obj 为null 则返回 空的Optional对象
6 用flatMap 可以构建 optional对象
s.f().flatMap(T::g)
s.f() 返回的是optional对象 T可以调用g()

收集结果

1 Stream可以调用 forEach方法 对每个元素应用函数
2 Stream对象可以调用 toArray 返回 object[]
可以调用toArray( String[]::new) 返回String[]
3 针对将流中的元素收集到另一个目标中,有一个便捷方法collect可用,它会接受一个Collector接口的实例
Collectors.toList()
Collectors.toSet()
Collectors.toCollection(TreeSet::new)
Collectors.joining(“x”) 拼接对象
4 如果要求数据的最小 最大 平均等,可以用summarizing函数

收集到map中

1 Collectors.toMap方法有两个函数引元,它们用来产生映射表的键和值
Collectors.toMap(Person::getName,Persong::getAge,(existingValue,newValue)->existingValue)
第三个可选的参数可以用来解决键的冲突

群组和分区

1 Collectors.groupingBy(Person.getCountry) ,返回一个 Map>
2 Collectors.partitionBy(…..) ,返回一个 Map>

下游收集器

1 群组和分区 默认用List来 包含对象, 如果需要其他容器,可以通过第二个参数作为下游收集器
2 Collectors.groupingBy(Person.getCountry,toSet())
3 基本的操作有
toSet(), counting() SummingInt(…get)

约简

1 reduce方法是一种用于从流中计算某个值的通用机制
stream().reduce(0,(x,y)->x+y)

基本类型流

1 将每个整数都包装到包装器对象中是很低效的,其他基本类型同理
2 流库中具有专门的类型IntStream、LongStream和DoubleStream
3 IntStream 可以用 IntStream.of 和 Arrays.of(int[]) 创建

并行流

1 通过paralleStream 创建 并行流,或者通过parallel方法 将顺序流转化为并行流
2 要确保传递给并行流操作的任何函数都可以安全地并行执行
3 注意 : 不要修改在执行某项流操作后会将元素返回到流中的集合
4 不要将所有的流都转换为并行流。只有在对已经位于内存中的数据执行大量计算操作时,才应该使用并行流