Java 8 新特性—Stream API 对元素流进行函数式操作

作者简介:大家好,我是smart哥,前中兴通讯、美团架构师,现某互联网公司CTO

联系qq:184480602,加我进群,大家一起学习,一起进步,一起对抗互联网寒冬

学习必须往深处挖,挖的越深,基础越扎实!

阶段1、深入多线程

阶段2、深入多线程设计模式

阶段3、深入juc源码解析


阶段4、深入jdk其余源码解析


阶段5、深入jvm源码解析

码哥源码部分

码哥讲源码-原理源码篇【2024年最新大厂关于线程池使用的场景题】

码哥讲源码【炸雷啦!炸雷啦!黄光头他终于跑路啦!】

码哥讲源码-【jvm课程前置知识及c/c++调试环境搭建】

​​​​​​码哥讲源码-原理源码篇【揭秘join方法的唤醒本质上决定于jvm的底层析构函数】

码哥源码-原理源码篇【Doug Lea为什么要将成员变量赋值给局部变量后再操作?】

码哥讲源码【你水不是你的错,但是你胡说八道就是你不对了!】

码哥讲源码【谁再说Spring不支持多线程事务,你给我抽他!】

终结B站没人能讲清楚红黑树的历史,不服等你来踢馆!

打脸系列【020-3小时讲解MESI协议和volatile之间的关系,那些将x86下的验证结果当作最终结果的水货们请闭嘴】

 

什么是 Stream API

Stream API 是 Java 8 引入的一个用于对集合数据进行函数式编程操作的强大的库。它允许我们以一种更简洁、易读、高效的方式来处理集合数据,可以极大提高 Java 程序员的生产力,是目前为止对 Java 类库最好的补充。

Stream API 的核心思想是将数据处理操作以函数式的方式链式连接,以便于执行各种操作,如过滤、映射、排序、归约等,而无需显式编写传统的循环代码。

下面是 Stream API 的一些重要概念和操作:

  1. Stream****(流)Stream 是 Java 8 中处理集合的关键抽象概念,它是数据渠道,用于操作数据源所生成的元素序列。这些数据源可以来自集合(Collection)、数组、I/O 操作等等。它具有如下几个特点:
    1. Stream 不会存储数据。
    2. Stream 不会改变源数据对象,它返回一个持有结果的新的 Stream
    3. Stream 操作是延迟执行的,这就意味着他们要等到需要结果的时候才会去执行。
  2. 中间操作:这些操作允许您在 Stream 上执行一系列的数据处理。常见的中间操作有 filter(过滤)、map(映射)、distinct(去重)、sorted(排序)、limit(截断)、skip(跳过)等。这些操作返回的仍然是一个 Stream。
  3. 终端操作:终端操作是对流进行最终处理的操作。当调用终端操作时,流将被消费,不能再进行进一步的中间操作。常见的终端操作包括 forEach(遍历元素)、collect(将元素收集到集合中)、reduce(归约操作,如求和、求最大值)、count(计数)等。
  4. 惰性求值:Stream 操作是惰性的,只有在调用终端操作时才会执行中间操作。这可以提高性能,因为只处理需要的数据。

为什么要用 Stream API

作为一个 CRUD Boy ,在实际开发中,我们的数据来源大多数都是基于数据库、文件等等,一般情况下这些数据都需要我们用 Java 程序来处理。这时有小伙伴就说,我用 for 循环就能很好的处理集合数据了,为什么偏要用 Stream API 呢?其实相比传统集合处理方式,Stream API 有很多优点:

  1. 简洁和可读性:Stream API 的链式操作使代码更加简洁、可读。
  2. 不可变性:Stream 操作不会修改原始数据,而是创建一个新的 Stream,确保了原始数据的不可变性,有助于并发编程。
  3. 惰性求值:Stream 操作是惰性的,只有在调用终端操作时才会触发中间操作的执行,提高了性能,因为只处理需要的数据。
  4. 并行处理:Stream API 支持并行处理数据,可以充分利用多核处理器,提高性能。
  5. 更高的效率:使用 Stream API 可以更快速地编写代码,因为它减少了样板代码的编写,同时提供了丰富的操作。

Stream 与集合的差异是:Stream 讲的是计算,而集合讲的是数据。

Stream 操作三部曲

一个完整的 Stream 操作包括三步

创建 Stream

首先我们需要一个 Stream 对象,常见的创建方式有:

  • 使用集合的 stream() 方法

在集合中有两个方法可以创建 Stream 对象:

default Stream<E> stream():返回一个顺序流
default Stream<E> parallelStream():返回一个并行流

  • 通过数组

Arrays.stream(T[] array),将数组转换为 Stream 对象:

String[] array = {"死磕 Java","死磕 Java 并发","死磕 Java 新特性","死磕 Netty"};
Stream<String> stream = Arrays.stream(array);
  • 使用Stream.of(T... values)方法
Stream<String> stream = Stream.of("死磕 Java","死磕 Java 并发","死磕 Java 新特性","死磕 Netty");

这种方式适用于直接提供一组元素来创建Stream。

  • 使用Stream.builder()方法

Stream 提供了一个 builder() 方法来提供构建 Stream 的构造器:

Stream.Builder<String> builder = Stream.builder();
builder.accept("死磕 Java");
builder.accept("死磕 Java 并发");
builder.accept("死磕 Java 新特性");
builder.accept("死磕 Netty");
Stream<String> stream = builder.build();

这种方式适用于需要逐个添加元素到Stream中的情况。

  • Stream.generate() or Stream.iterate(T seed, UnaryOperator<T> f)

这两个方法都是用于生成无限元素的Stream,需要通过limit()方法来限制元素数量。

Stream<String> stream = Stream.generate(() -> "a").limit(3);

这两个方法使用比较少。

中间操作

有了 Stream 对象,就可以在 Stream 上应用中间操作。

中间操作是一系列的操作,对数据源的数据进行处理,例如过滤、映射、排序、去重等等。注意这些操作不会立即执行,而是构建一个操作链。下表是 Stream 中常用中间操作方法。

方法名 描述
filter(Predicate<T> predicate) 根据给定的谓词条件过滤元素。
map(Function<T, R> mapper) 将元素通过给定的函数映射为另一个类型的元素。
flatMap(Function<T, Stream<R>> mapper) 将每个元素映射为一个流,然后将这些流合并为一个流。
distinct() 去除流中的重复元素。
sorted() 对元素进行排序,默认按自然顺序排序。
sorted(Comparator<T> comparator) 使用
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值