JDK1.8_Stream_流式操作

Stream

Stream是Java 8中处理集合的关键抽象概念,可以执行非常复杂的查找、过滤、和映射数据操作,使用Stream API对集合数据进行操作,就类似使用SQL执行的数据库查询。Stream不是集合元素,它不是数据结构并不保存数据,它是有关算法和计算的,它更像一个高级版本的Iterator。Iterator只能显式地一个一个去遍历元素并对其执行某些操作,而使用Stream,只要给出需要对其包含的元素执行什么操作,Stream会隐式地在内部进行遍历,做出相应的数据转换。和迭代器又不同的是,Stream可以并行化操作,迭代器只能命令式地、串行化操作。

Stream和Collection的区别主要有

  • stream本身并不存储数据,数据是存储在对应的collection里,或者在需要的时候才生成的
  • stream不会修改数据源,总是返回一个持有结果的新的stream
  • stream的操作是懒执行的:仅当最终的结果需要的时候才会执行,比如上面的例子中,结果仅需要前3个长度大于7的字符串,那么在找到前3个长度符合要求的字符串后,filter()将停止执行
Stream操作步骤
  • 创建Stream
  • 中间操作
  • 终止操作
创建Stream
//1.通过Collection集合提供的stream() 或parallelStream
List<String> list= new ArrayList<>();
list.stream()
//2.通过Arrays的静态方法,传入一个泛型数组,创建一个流
String [] streamArr= new String []{"1","2","3","4"};
Arrays.stream(streamArr);
//3.通过Stream的静态方法,传入一个泛型数组,或者多个参数,创建一个流,他的底层也是使用的Arrays的stream方法
Stream.of(streamArr);
//4.创建无限流
//迭代
Stream.iterate()
//生成
Stream.generate()

中间操作

中间操作的返回值都是一个新流。多个中间操作可以连接起来形成一个流水线,除非流水线上触发终止操作,否则中间操作不会执行任何的处理,而在终止操作时一次性全部处理,这种处理被称为惰性求值

筛选与切片
  • filter
    接收一个Predicate,从流中排除某些元素,返回满足条件的流
  • limit
    截断,使元素不超过给定数量
  • skip
    跳过元素,返回一个扔掉了前n个元素的流,若流中的元素不足n个,则返回一个空流
  • distinct
    筛选,通过流所生成元素的hashCode和equals去去除重复元素,需要重写这两个方法
映射
  • map
    接受一个函数型接口作为参数,将元素转换成其他形式,或用于提取信息
  • flatMap
    接受一个函数型接口作为参数,将流中的每个值都转换成另一个流,然后把所有的流连接成一个流,这个方法和map的区别是,会将所有的映射元素封装成一个对象
排序
  • sorted
    产生一个新流,其中按自然顺序排序,也可以传入一个Comparator接口,按照比较器排序
终止操作
查找与匹配
  • allMatch
    检查是否匹配所有元素,全都满足才返回true,流为空时总是返回true
  • anyMatch
    检查是否至少匹配一个元素,有一个满足条件就返回true
  • noneMatch
    检查是否没有匹配所有的元素,全都不满足返回true
  • findeFirst
    返回第一个元素(可以配合排序使用)
  • findAnt
    返回当前流中的任意元素(可以用来返回某种状态的任意一个对象,配合并行流使用)
  • count
    返回当前流中的元素的总个数
  • max
    返回流中的最大值(排序后的第一个)
  • min
    返回流中的最小值(排序后的最后一个)
  • forEach
    内部迭代
归约
  • reduce
    reduce操作将流中的元素根据指定的计算模型,反复结合起来,得到一个值。之前提到count、sum、min和max方法,因为常用而被纳入标准库中,其实这些都是reduce操作
//reduce方法有三个override的方法
//对Stream中的数据通过累加器accumulator迭代计算,最终得到一个Optional对象
Optional<T> reduce(BinaryOperator<T> accumulator);
//给定一个初始值identity,通过累加器accumulator迭代计算,得到一个同Stream中数据同类型的结果
T reduce(T identity, BinaryOperator<T> accumulator);
//给定一个初始值identity,通过累加器accumulator迭代计算,得到一个identity类型的结果,第三个参数用于使用并行流时合并结果
U reduce(U identity,BiFunction<U, ? super T, U> accumulator,BinaryOperator combiner);

函数式接口BinaryOperator,该函数式接口需要两个参数,返回一个结果(reduce中返回的结果会作为下次累加器计算的第一个参数),也就是所讲的累加器。如果不指定初始值,使用第一个方法,Stream中的第一个元素会作为初始值。

收集
  • collect
    将流转化为其他形式,接收一个Collector接口的实现,用于给Stream中的元素做汇总

Collectors实用类提供了很多的静态方法,可以方便的创建常见收集器的实例
Collectors类常用方法
toList
toSet
toCollection
counting
summingInt
averagingInt
汇总 summarizingInt

IntSummaryStatistics summaryStatistics =personList.stream()
                                .collect(Collectors.summarizingInt(PersonBean::getSalary));
summaryStatistics.getCount();
summaryStatistics.getMax();
summaryStatistics.getMin();
summaryStatistics.getSum()

字符串连接 joining
maxBy
minBy
分组 groupingBy

// 根据年龄分组
Map<String, List<PersonBean>>personMapByAge =
                    personList.stream()
                                 .collect(Collectors.groupingBy(PersonBean::getUserAge));
// 分组,并统计每个组的个数
Map<String, Long> personMapByAgeNum =
                    personList.stream()
                                 .collect(Collectors
                                 .groupingBy(PersonBean::getUserAge, Collectors.counting()));
// 根据年龄分组,并统计每个组的工资和
Map<String, Integer>personMapBySalarySum = 
                    personList.stream()
                                 .collect(Collectors
                                 .groupingBy(PersonBean::getUserAge,Collectors
                                 .summingInt(PersonBean::getSalary)));
// 根据年龄和性别分组,多分组的话Map可无限嵌套
Map<String, Map<String, List<PersonBean>>>personMapByAgeAndSex
                   = personList.stream()
                                   .collect(Collectors
                                   .groupingBy(PersonBean::getUserAge, Collectors
                                   .groupingBy(PersonBean::getUserSex)));

分区 partitioningBy

Collector<T, ?, Map<Boolean, List<T>>> 
partitioningBy(Predicate<? super T> predicate) {
        return partitioningBy(predicate, toList());
    }
组合
  • concat
    用来连接类型一样的两个流
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值