一文掌握Java Stream API

在这里插入图片描述

引言

Java Stream API 自 Java 8 引入以来,已成为处理集合数据的强大工具。它不仅提高了代码的可读性,还优化了性能,使得集合操作变得更加简洁和高效。本文将深入探讨如何利用 Stream API 的常用操作,帮助你更好地掌握这一强大的功能。

Java Stream API 简介

Java Stream 是 Java 8 引入的一种新的抽象层,专门用于简化集合对象的处理过程。它提供了一种更加简洁和函数式的方式来处理数据,使得开发者能够编写出更加清晰和易于维护的代码。Stream 操作可以是中间操作,也可以是终端操作,中间操作返回的是Stream,所以我们可以链式调用;终端操作返回的是一个结果或者是null。

示例:
假设我们有一个 Person 类,其中包含 nameage 两个属性,现在我们有一个 Person 对象的列表,我们想要找出其中年龄大于20的所有人,并按照年龄升序排序。

List<Person> people = Arrays.asList(new Person("Alice", 23),new Person("Bob", 20),new Person("Charlie", 24)
);
// 使用Stream进行过滤和排序
List<Person> result = people.stream()
.filter(person -> person.getAge() > 20) // 过滤出年龄大于20的人
.sorted(Comparator.comparing(Person::getAge)) // 根据年龄升序排序
.collect(Collectors.toList()); // 收集结果到一个列表中
// 输出结果
result.forEach(System.out::println);

在这个示例中,我们首先创建了一个包含三个 Person 对象的列表。然后,我们调用 stream() 方法将列表转换为 Stream。接下来,我们使用 filter 方法来过滤出年龄大于20的人,使用 sorted 方法根据年龄进行升序排序,最后使用 collect 方法将结果收集到一个新的列表中。

超级常用操作

求交集和差集

通过使用 filter 和 map 方法,我们可以轻松地实现这些集合操作,从而提高代码的可读性和效率。

示例:
假设我们有两个整数列表,我们想要找出这两个列表的交集和差集。

List<Integer> list1 = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> list2 = Arrays.asList(4, 5, 6, 7, 8);// 求交集
List<Integer> intersection = list1.stream().filter(list2::contains) // 筛选出同时存在于list2中的元素.collect(Collectors.toList()); // 收集结果到一个新的列表System.out.println("交集: " + intersection);// 求差集
List<Integer> difference = list1.stream().filter(element -> !list2.contains(element)) // 筛选出不存在于list2中的元素.collect(Collectors.toList()); // 收集结果到一个新的列表System.out.println("差集: " + difference);

在这个示例中,我们首先定义了两个整数列表 list1list2。然后,我们使用 stream() 方法将 list1 转换为 Stream。接下来,我们使用 filter 方法来筛选出同时存在于 list2 中的元素,从而得到两个列表的交集。同样地,我们使用 filter 方法来筛选出不存在于 list2 中的元素,从而得到 list1 相对于 list2 的差集。最后,我们使用 collect 方法将结果收集到新的列表中,并打印出交集和差集。

排序

在Java的Stream API中,sorted()方法提供了一种快捷且灵活的方式来对集合中的元素进行排序。这个方法可以直接对元素进行自然排序,或者通过提供一个自定义的比较器来实现定制排序。这种操作对于处理大量数据时尤其有用,因为它允许开发者以声明式的方式来表达排序逻辑,而不是手动实现排序算法。

  • 示例:
    假设我们有一个学生列表,每个学生都有姓名和分数两个属性,我们想要根据分数对学生进行升序排序。
List<Student> students = Arrays.asList(new Student("Alice", 90),new Student("Bob", 85),new Student("Charlie", 92)
);
// 使用Stream进行排序
List<Student> sortedStudents = students.stream().sorted(Comparator.comparingInt(Student::getScore)) // 根据分数进行升序排序.collect(Collectors.toList()); // 收集排序后的结果
// 输出排序后的学生信息sortedStudents.forEach(student -> System.out.println(student.getName() + ": " + student.getScore()));

在这个示例中,我们首先创建了一个包含三个 Student 对象的列表。然后,我们调用 stream() 方法将列表转换为 Stream。接下来,我们使用 sorted 方法并提供一个比较器,根据学生的分数进行升序排序。最后,我们使用 collect 方法将排序后的结果收集到一个新的列表中,并打印出每个学生的姓名和分数。

Stream.Builder

Stream.Builder 是 Java 8 引入的一个接口,用于更灵活地构建 Stream 流。与直接从集合或数组创建流相比,Stream.Builder 提供了一种逐个添加元素的方式,使得我们可以在构建流的过程中动态地添加元素,这在处理动态数据源或需要在运行时决定元素的场景下非常有用。

示例:
考虑一个场景,我们需要创建一个字符串流,并对这个流进行一系列的操作。我们可以使用 Stream.Builder 来逐个添加字符串元素,然后构建成一个流。

在这个示例中,我们首先创建了一个 Stream.Builder 对象,然后使用 add 方法逐个添加了三个字符串元素。最后,我们调用 build 方法构建了一个流,并对这个流进行了遍历打印操作。

// 导入必要的类
import java.util.stream.Stream;// 主类定义
public class StreamBuilderExample {// 主函数public static void main(String[] args) {// 创建一个 Stream.Builder 对象Stream.Builder<String> builder = Stream.builder();// 逐个添加字符串元素到流构建器builder.add("zhangsan"); // 添加张三builder.add("lisi"); // 添加李四builder.add("wangmazi"); // 添加王麻子// 构建并获取流Stream<String> stream = builder.build();// 遍历流,打印每个元素stream.forEach(System.out::println);}
}

从数组创建流

可以使用Arrays.stream()方法从数组创建流。

示例

  • 假设有一个整数数组,我们想要找出其中的偶数,并将其乘以2。

  • 原始数组:[1, 2, 3, 4, 5, 6]

  • 操作后的结果:[4, 8, 12]

  • 代码片段

    // 引入必要的包
    import java.util.Arrays;
    import java.util.List;
    import java.util.stream.Collectors;public class ArrayToStream {public static void main(String[] args) {// 定义一个整数数组int[] numbers = {1, 2, 3, 4, 5, 6};// 使用Arrays.stream()方法从数组创建流,然后进行过滤和映射操作List<Integer> result = Arrays.stream(numbers).filter(n -> n % 2 == 0) // 过滤出偶数.map(n -> n * 2) // 将偶数乘以2.boxed() // 将IntStream转换为Stream<Integer>.collect(Collectors.toList()); // 将结果收集到列表中// 输出结果System.out.println(result); // 输出:[4, 8, 12]}
    }
    

从集合创建流

可以通过调用集合的stream()方法直接获取一个流对象。

示例

  • 假设有一个人名列表,我们想要找出长度大于3的人名,并将其转换为大写。

  • 原始列表:["Tom", "Jerry", "Alice", "Bob", "Catherine"]

  • 操作后的结果:["JERRY", "ALICE", "CATHERINE"]

  • 代码片段

    List<String> names = Arrays.asList("Tom", "Jerry", "Alice", "Bob", "Catherine");
    List<String> filteredNames = names.stream().filter(name -> name.length() > 3).map(String::toUpperCase).collect(Collectors.toList());
    

迭代中使用元素索引

在Java 8的Stream API中,直接获取正在迭代的元素的索引并不是一件直接的事情。但是,我们可以通过一些间接的方法来实现这一点,比如使用 IntStreammapToObj 方法。这样做不仅使代码更加灵活,而且还保持了代码的简洁性和可读性。

示例:
假设我们有一个字符串列表,我们想要打印出每个字符串及其在列表中的索引。

List<String> words = Arrays.asList("zhangsan", "lisi", "wangmazi");// 使用IntStream和mapToObj进行迭代
IntStream.range(0, words.size()).mapToObj(index -> "索引: " + index + ", 值: " + words.get(index))  // 获取索引和对应的值.forEach(System.out::println);  // 打印结果

在这个示例中,我们首先定义了一个包含三个字符串的列表 words。然后,我们使用 IntStream.range 方法创建一个从0到 words.size() 的整数流,其中每个整数代表一个索引。接下来,我们使用 mapToObj 方法将每个索引映射到一个字符串,这个字符串包含索引和对应的列表元素。最后,我们使用 forEach 方法来打印出结果。

总结

通过本文的介绍,你应该已经掌握了如何使用 Java Stream API 进行集合操作,包括求交集和差集等。掌握这些技能不仅能够提升你的编程效率,还能帮助你写出更加简洁、高效的代码。


最近很多小伙伴,让我帮忙找一套 Java 学习资料,于是我翻遍了收藏的 1024G 资料,找到一套华为工程师总结的 Java 笔记,可以说是 Java 程序员必备!

整个资料包内容专注 Java 技术,包括 Spring、Spring Boot/Cloud、Dubbo、JVM、集合、多线程、JPA、MyBatis、MySQL、大数据、Nginx、Git、Docker、GitHub、Servlet、JavaWeb、IDEA、Redis、算法、面试题等几乎覆盖了 Java 基础和进阶的方方面面,非常适合初学者入门和进阶者巩固知识!

据说已经有小伙伴通过这套资料,成功的入职了蚂蚁金服、今日头条等大厂。而且,这些资料不是扫描版的,里面的文字都可以直接复制,非常便于我们学习!

分享在这里~
链接:https://pan.baidu.com/s/1qPcZxxoMUqEGhxNLNusdaQ?pwd=lird
提取码:lird
在这里插入图片描述
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/157952.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

坚持#第420天~阿里云轻量服务器内存受AliYunDunMonito影响占用解决方法

阿里云轻量服务器内存受AliYunDunMonito影响占用解决方法&#xff0c;亲测有效&#xff1a; Mobax好卡啊&#xff0c;那就直接在阿里云后台操作即可&#xff0c;阿里云后台也可以上传文件。 Navicat mysql好卡啊&#xff0c;那就直接在阿里云后台最上面帮助的右边有个数据库&…

jenkins实践篇(2)—— 自动打tag的可回滚发布模式

大家好&#xff0c;我是蓝胖子&#xff0c;在上一篇我简单介绍了如何基于特定分支做自动编译和发布&#xff0c;在生产环境中&#xff0c;为了更加安全和快速回滚&#xff0c;我采取的是通过对代码打tag的方式来进行部署&#xff0c;下面我将详细介绍整个发布过程的逻辑。 发布…

【Java 进阶篇】Java ServletContext详解:在Web应用中获取全局信息

在Java Web开发中&#xff0c;ServletContext是一个重要的概念&#xff0c;它允许我们在整个Web应用程序中共享信息和资源。本篇博客将深入探讨ServletContext的作用、如何获取它&#xff0c;以及如何在Web应用中使用它。无论您是刚刚入门的小白还是有一定经验的开发者&#xf…

Python---字符串切片-----序列名称[开始位置下标 : 结束位置下标 : 步长]

字符串切片&#xff1a;是指对操作的对象截取其中一部分的操作。字符串、列表、元组都支持切片操作。 本文以字符串为例。 基本语法&#xff1a; 顾头不顾尾&#xff1a; ----------类似range&#xff08;&#xff09; 范围&#xff0c;顾头不顾尾 相关链接Python----ran…

mac录屏快捷键指南,轻松录制屏幕内容!

“大家知道mac电脑有录屏快捷键吗&#xff0c;现在录屏不太方便&#xff0c;每次都花很多时间&#xff0c;要是有录屏快捷键&#xff0c;应该会快速很多&#xff0c;可是哪里都找不到&#xff0c;有人知道吗&#xff1f;帮帮我&#xff01;” 苹果的mac电脑以其精美的设计和卓…

照片编辑软件Affinity Photo 2 for Mac v2.1.1中文激活版 2024年最新中文版下载

照片编辑软件Affinity Photo 2 for Mac v2.1.1中文激活版是一款功能强大的专业级图像编辑软件&#xff0c;由Serif公司开发。它提供了广泛的工具和功能&#xff0c;适用于摄影师、设计师和艺术家。 照片编辑软件Affinity Photo 2 for Mac v2.1.1中文激活版软件介绍 TIFF&#…

javafaker测试数据生成实战

javafaker测试数据生成实战 1.背景2.介绍2.1 特点 3. 使用3.1 基础使用3.1.1 maven依赖3.1.1 使用示例 3.2 进阶使用3.1 生成中文信息3.2 根据姓名生成账号3.2.1 maven依赖3.2.2 中文转拼音工具类 3.3 高级使用3.3.1 中文性名重复处理方案1: 偷懒方式方案2: 较真模式 1.背景 最…

经验总结2023-11-2

axios发起post请求的方式&#xff1a; 要解决跨域问题&#xff0c;后端要加&#xff0c;指定支持的方法是Pos还是get&#xff1a;

玻色量子签约移动云“五岳”量子云计算创新加速计划!

2023年4月24-26日&#xff0c;由中国移动通信集团主办的“云擎未来 智信天下”2023移动云大会在苏州圆满落幕。 中国移动在本次大会发布了“五岳”量子云计算创新加速计划。作为中国移动量子计算方向的战略伙伴&#xff0c;玻色量子创始人&CEO文凯博士代表北京玻色量子科技…

干货!数字IC后端入门学习笔记

很多同学想要了解IC后端&#xff0c;今天大家分享了数字IC后端的学习入门笔记&#xff0c;供大家学习参考。 很多人对于后端设计的概念比较模糊&#xff0c;需要做什么也都不甚清楚。 有的同学认为就是跑跑 flow、掌握各类工具。 事实上&#xff0c;后端设计的工作远不止于此。…

(3)小程序如何绑定事件

<view bindtap"led">日志</view> 一&#xff1a;用什么绑定事件&#xff1f; 用这个bindtap 在框架中绑定事件 二&#xff1a;在ts文件中如何去操作 led:function(){console.log(this.data.message)this.setData({message: "现在"})}led&am…

Hadoop相关知识点

文章目录 一、主要命令二、配置虚拟机2.1 设置静态ip2.2 修改主机名及映射2.3 修改映射2.4 单机模式2.5 伪分布式2.6 完全分布式 三、初识Hadoop四、三种模式的区别4.1、单机模式与伪分布式模式的区别4.2、特点4.3、配置文件的差异4.3.1、单机模式4.3.2、伪分布式模式4.3.3、完…