Stream流详情

StreamJava 8 API添加的一个新的抽象,称为流Stream,以一种声明性方式处理数据集合(侧重对于源数据计算能力的封装,并且支持序列与并行两种操作方式)

Stream流是对集合(Collection)对象功能的增强,与Lambda表达式结合,可以提高编程效率、间接性和程序可读性。

特点

1、代码简洁函数式编程写出的代码简洁且意图明确,使用stream接口让你从此告别for循环

2、多核友好:Java函数式编程使得编写并行程序如此简单,就是调用一下方法

流程

1、将集合转换为Stream流(或者创建流)

2、操作Stream流(中间操作,终端操作)

stream流在管道中经过中间操作(intermediate operation)的处理,最后由最终操作(terminal operation)得到前面处理的结果

BaseStream:基础接口,声明了流管理的核心方法;

Stream:核心接口,声明了流操作的核心方法,其他接口为指定类型的适配

一、流创建操作

生成流的方式主要有五种

1.Stream创建

2.Collection集合创建(应用中最常用的一种

3.Array数组创建

通过Arrays.stream方法生成流,并且该方法生成的流是数值流【即IntStream】而不是 Stream

注:

使用数值流可以避免计算过程中拆箱装箱,提高性能。

Stream API提供了mapToInt、mapToDouble、mapToLong三种方式将对象流【即Stream 】转换成对应的数值流,同时提供了boxed方法将数值流转换为对象流

4.文件创建

通过Files.line方法得到一个流,并且得到的每个流是给定文件中的一行

5.函数创建
iterator

iterate方法接受两个参数,第一个为初始化值,第二个为进行的函数操作,因为iterator生成的流为无限流,通过limit方法对流进行了截断,只生成5个偶数 

generator

generate方法接受一个参数,方法参数类型为Supplier ,由它为流提供值。generate生成的流也是无限流,因此通过limit对流进行了截断

Stream中的静态方法:of()、iterate()、generate()

BufferedReader.lines() 方法,将每行内容转成流

Pattern.splitAsStream() 方法,将字符串分隔成流 

二、操作符

流的操作类型主要分为两种:中间操作符、终端操作符

(一)中间操作符

通常对于Stream的中间操作,可以视为是源的查询,并且是懒惰式的设计,对于源数据进行的计算只有在需要时才会被执行,与数据库中视图的原理相似;

Stream流的强大之处便是在于提供了丰富的中间操作,相比集合或数组这类容器,极大的简化源数据的计算复杂度

一个流可以跟随零个或多个中间操作。其目的主要是打开流,做出某种程度的数据映射/过滤,然后返回一个新的流,交给下一个操作使用

这类操作都是惰性化的,仅仅调用到这类方法,并没有真正开始流的遍历,真正的遍历需等到终端操作时,常见的中间操作有下面即将介绍的 filter、map 等

1、filter;过滤

用于通过设置的条件过滤出元素

根据对象属性去重

collectingAndThen 这个方法的意思是: 将收集的结果转换为另一种类型。

上面的方法可以看成set转换为ArrayList

2.Map

新值类型和原来的元素的类型相同示例

 新值类型和原来的元素的类型不同示例

map的原型为:<R> Stream<R> map(Function<? super T, ? extends R> mapper); 

上边例子中,将Student::getAge作为参数,其实际为:<R> Stream<Integer> map(Function<? super Student, ? extends Integer> mapper);

3、distinct:去重

 返回一个元素各异(根据流所生成元素的hashCode和equals方法实现)的流

4.Sorted

返回排序后的流
原始类型排序

对象单字段排序

对象多字段、全部升序排序

对象多字段、升序+降序

5、limit

会返回一个不超过给定长度的流

6、skip

返回一个扔掉了前n个元素的流

7、flatMap

使用flatMap方法的效果是,各个数组并不是分别映射成一个流,而是映射成流的内容。所有使用map(Arrays::stream)时生成的单个流都被合并起来,即扁平化为一个流

map:对流中每一个元素进行处理
flatMap:流扁平化,让你把一个流中的“每个值”都换成另一个流,然后把所有的流连接起来成为一个流 
本质区别:map是对一级元素进行操作,flatmap是对二级元素操作map返回一个值;flatmap返回一个流,多个值

应用场景:map对集合中每个元素加工,返回加工后结果;flatmap对集合中每个元素加工后,做扁平化处理后(拆分层级,放到同一层)然后返回

8、peek

对元素进行遍历处理

(二)终端操作符

Stream流执行完终端操作之后,无法再执行其他动作,否则会报状态异常,提示该流已经被执行操作或者被关闭,想要再次执行操作必须重新创建Stream流

一个流有且只能有一个终端操作,当这个操作执行后,流就被关闭了,无法再被操作,因此一个流只能被遍历一次,若想在遍历需要通过源数据在生成流。

终端操作的执行,才会真正开始流的遍历。如 count、collect 等

1、collect

收集器,将流转换为其他形式收集器,将流转换为其他形式

2、forEach

遍历流

3、findFirst

返回第一个元素

4、findAny

将返回当前流中的任意元素

5、count

返回流中元素总数

6、sum

求和

7、max

最大值

8、min

最小值

9、anyMatch

检查是否至少匹配一个元素,返回boolean

10、allMatch

检查是否匹配所有元素,返回boolean

11、noneMatch

检查是否没有匹配所有元素,返回boolean

12、reduce

可以将流中元素反复结合起来,得到一个值

三、Collect收集

Collector:结果收集策略的核心接口,具备将指定元素累加存放到结果容器中的能力;并在Collectors工具中提供了Collector接口的实现类

1、toList

将用户ID存放到List集合中

2、toMap

将用户ID和Name以Key-Value形式存放到Map集合中

3.toSet

将用户所在城市存放到Set集合中

4、counting

符合条件的用户总数

5、summingInt

对结果元素即用户ID求和

6、minBy

筛选元素中ID最小的用户

7、joining

将用户所在城市,以指定分隔符链接成字符串;

8、groupingBy

按条件分组,以城市对用户进行分组

1、orElse(null)

表示如果一个都没找到返回null(orElse()中可以塞默认值。如果找不到就会返回orElse中设置的默认值)

  1. orElseGet(null)
  2. 表示如果一个都没找到返回null(orElseGet()中可以塞默认值。如果找不到就会返回orElseGet中设置的默认值)

    orElse() 接受类型T的 任何参数,而orElseGet()接受类型为Supplier的函数接口,该接口返回类型为T的对象

  3. orElse(null)和orElseGet(null)区别:

    1、当返回Optional的值是空值null时,无论orElse还是orElseGet都会执行

    2、而当返回的Optional有值时,orElse会执行,而orElseGet不会执行

  • 9
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值