Java8 Stream流使用及其基本原理

Stream流,是对集合对象操作的增强

基本使用

比如有一个Person类的集合:List<Person> personList,可以通过stream()对集合中的元素进行操作,

下面的操作流程可以归纳为 过滤-映射-收集。

List<Integer> personIdList = personList.stream()     //选出年龄大于20的Person对象        .filter(person -> person.getAge() > 20)        //将Person对象映射成为它的属性id     .map(Person::getId)     //收集为List集合        .collect(Collectors.toList());

上述代码获取到了,年龄大于20岁的人id集合。

在 过滤-映射-收集 这个流程中:

    过滤和映射属于中间操作,当操作结束时才会触发计算,可以高效地迭代大集合

  收集属于结束操作,触发计算。

中间操作和结束操作

流操作可以分为 中间操作(惰性求值) 和 结束操作

中间操作指,操作过程中只记录操作而不做执行,直到执行结束操作,才会触发实际的操作,即惰性求值。

  中间操作又分为:

    无状态操作,元素处理不受之前元素影响,比如map()、filter()、skip()、peek()等

    有状态操作,需要拿到所有元素才能进行,比如sorted()、limit()、distinct()等

结束操作是指,拿到所有元素后才能进行的操作。

  结束操作又分为:

    短路操作,遇到符合条件的元素后就可以终止,比如anyMatch()、findFirst()、findAny()等

    非短路操作,需要处理所有元素,比如forEach()、collect()、max()、count()等。

例子

1.将List<Person>映射成一个Map,key为Person的id属性,value为Person实体类

Map<Integer, Person> PersonMap= personList.stream()        .collect(Collectors.toMap(Person::getId, person -> person));

2.得到一个Map<Integer,List<Person>>集合,key为Person的age属性,value是按年龄分组后的Person对象集合:

Map<Integer, List<Person>> personsMap = personList.stream()        .collect(Collectors.groupingBy(Person::getAge));

3.统计所有人年龄的总和:

int personAgeSum = personList.stream()     //根据age属性转换成IntStream        .mapToInt(Person::getAge)        .sum();

4.选出List集合中创建时间最晚的数据(createtime属性为Date类型)

UserInfo userInfoMax = userInfos.stream()     .max(Comparator.comparing(UserInfo::getCreateTime))        .get();  

这里的max方法实际返回的是Optional<UserInfo>对象该对象可以通过orElse()方法设置对象UserInfo为null时的值:
UserInfo userInfoMax = userInfos.stream().max(Comparator.comparing(UserInfo::getCreateTime))        .orElse(为null时的值); //这里如果max返回的对象为null(一般情况不会是),会取orElse()中的值

5.将所有小写字母拼接起来

String concat = Stream.of("a", "B", "c", "D", "e", "F")
                .filter(x -> x.compareTo("Z") > 0)
                .reduce("", String::concat);

reduce方法的第一个参数是起始值,第二个参数是流中的元素,迭代流中的数据

也可以只传一个参数,即不指定起始值,这样会返回一个Optional对象

String concat = Stream.of("a", "B", "c", "D", "e", "F")
                .filter(x -> x.compareTo("Z") > 0)
                .reduce(String::concat)
                .orElse("");

性能及基本原理简述

Stream 顾名思义,相当于批量处理数据的流水线。

在处理一般的数据量下,使用循环方式处理集合和通过stream方式处理集合的性能相差不大,但在数据里更大逻辑更复杂的情况下stream要更优。

而parallelStream并行流,利用多核处理器的优势,并行处理数据(这意味着所处理的数据,不应该和顺序相关,否则会因为并行得到错误的结果),能够显著的提高执行速度。

Stream处理过程简述:

首先将Collection转化为Stream,流上的每个结点都只会返回包含上一结点引用的中间结点,使结点们组成了一个双向链表结构,而不会立即进行任何数据处理。

每个中间操作都实现了Sink接口,实现了 makeSink() 方法用来返回自己的 Sink 实例,

只有当终止操作出现时,才开始将 Sink 实例化执行数据处理,

无状态操作的 Sink 接收到数据,会立即通知下游,有状态操作的 Sink 则会等要处理的数据处理完了才开始通知下游,

终止节点将数据收集起来后就完成了这次操作。

参考文章:

https://www.cnblogs.com/CarpenterLee/archive/2017/03/28/6637118.html

https://zhuanlan.zhihu.com/p/52579165

https://zhuanlan.zhihu.com/p/47478339

原文地址:https://www.cnblogs.com/gss128/p/11032504.html

时间: 2024-08-04 02:12:51

Java8 Stream流使用及其基本原理的相关文章

Java8 Stream流

Java8 Stream流 Java8关于map和flatMap的代码片段思考 Java8初体验(二)Stream语法详解 distinct() /* 返回一个流包含不同的元素(根据equals方法判断,null值并不会报空指针异常,会保留一个null). 对于有序的流保证稳定性,保留最先出现的元素,对于无序的流不保证稳定性. */ /** * Returns a stream consisting of the distinct elements (according to * {@link

【转】Java8 Stream 流详解

  当我第一次阅读 Java8 中的 Stream API 时,说实话,我非常困惑,因为它的名字听起来与 Java I0 框架中的 InputStream 和 OutputStream 非常类似.但是实际上,它们完全是不同的东西. Java8 Stream 使用的是函数式编程模式,如同它的名字一样,它可以被用来对集合进行链状流式的操作. 本文就将带着你如何使用 Java 8 不同类型的 Stream 操作.同时您还将了解流的处理顺序,以及不同顺序的流操作是如何影响运行时性能的. 我们还将学习终端

java8 stream流操作

Stream 在对流进行处理时,不同的流操作以级联的方式形成处理流水线.一个流水线由一个源(source),0 到多个中间操作(intermediate operation)和一个终结操作(terminal operation)完成. 源:源是流中元素的来源.Java 提供了很多内置的源,包括数组.集合.生成函数和 I/O 通道等. 中间操作:中间操作在一个流上进行操作,返回结果是一个新的流.这些操作是延迟执行的. 终结操作:终结操作遍历流来产生一个结果或是副作用.在一个流上执行终结操作之后,该

关于Java8 Stream流的利与弊 Java初学者,大神勿喷

1:第一个队伍只要名字为3个字成员的姓名,存储到新集合 2:第一个队伍筛选之后只要前3人:存储到一个新集合 3:第2个队伍只要姓张的成员姓名:存储到一个新集合 4:第2个队伍不要前2人,存储到一个新集合 5:将2个队伍合并到一个队伍,存储到一个新集合 6:根据姓名创建Person对象,存储到一个新集合 //使用普通方法进行筛选 前面加了一个时间类 import java.util.ArrayList;public class Demo08List { public static void mai

Java8 Stream流API常用操作

Java版本现在已经发布到JDK13了,目前公司还是用的JDK8,还是有必要了解一些JDK8的新特性的,例如优雅判空的Optional类,操作集合的Stream流,函数式编程等等;这里就按操作例举一些常用的Stream流操作; Stream流简介 A sequence of elements supporting sequential and parallel aggregate operations. Stream流是一个来自数据源的元素队列并支持聚合操作 Stream流中常用方法的分类 1.

Java8 Stream流方法

流是Java API的新成员,它允许以声明性方式处理数据集合(通过查询语句来表达,而不是临时编写一个实现).就现在来说,可以把它们看成遍历数据集的高级迭代器.此外,流还可以透明地并行处理,无需写任何多线程代码了! 流的使用一般包括三件事: •一个数据源(如集合)来执行一个查询: •一个中间操作链,形成一条流的流水线: •一个终端操作,执行流水线,并能生成结果. 流方法 含义 示例 filter (中间操作)该操作会接受一个谓词(一个返回boolean的函数)作为参数,并返回一个包括所有符合谓词的

Java8 Stream 流使用场景和常用操作

JAVA8内置的函数式编程接口应用场景和方式 pojo类对象和默认创建list的方法 import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import java.util.ArrayList; import java.util.List; @Data @AllArgsConstructor @NoArgsConstructor public class DotaHero {

java8 stream流操作的flatMap(流的扁平化)

https://mp.weixin.qq.com/s/7Fqb6tAucrl8UmyiY78AXg https://blog.csdn.net/Mark_Chao/article/details/80810030 原文地址:https://www.cnblogs.com/alter888/p/11966114.html

Java8新特性——stream流

一.基本API初探 package java8.stream; import java.util.Arrays; import java.util.IntSummaryStatistics; import java.util.List; import java.util.Random; import java.util.stream.Collectors; import java.util.stream.IntStream; /** * @author [email protected] * @