一文掌握Java Stream API

news2025/4/27 16:02:52

在这里插入图片描述

引言

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.coloradmin.cn/o/1161628.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

算法模板之队列解密 | 图文详解

&#x1f308;个人主页&#xff1a;聆风吟 &#x1f525;系列专栏&#xff1a;数据结构、算法模板、汇编语言 &#x1f516;少年有梦不应止于心动&#xff0c;更要付诸行动。 文章目录 &#x1f4cb;前言一. ⛳️模拟队列1.1 &#x1f514;用数组模拟实现队列1.1.1 &#x1f47…

解决远程桌面 这可能是由于CredSSP加密数据库修正问题

运行环境 : Windows Server 2012 R2 Standard 解决方式 策略组 gpedit.msc&#xff0c;注册表 regedit 等方式都尝试无效时&#xff0c;可尝试把下面这个勾勾去掉。

【小黑嵌入式系统第七课】PSoC® 5LP 开发套件(CY8CKIT-050B )——PSoC® 5LP主芯片、I/O系统、GPIO控制LED流水灯的实现

上一课&#xff1a; 【小黑嵌入式系统第六课】嵌入式系统软件设计基础——C语言简述、程序涉及规范、多任务程序设计、状态机建模(FSM)、模块化设计、事件触发、时间触发 文章目录 一、PSoC 5LP主芯片二、PSoC 5LP I/O系统(1) I/O系统特性(2) I/O系统怎样运作&#xff1f;1、I/…

【PC】神秘市场2023

神秘市场2023 我们有一个令人振奋的消息要告诉大家&#xff0c;神秘市场要开张了&#xff01; 据可靠情报&#xff0c;这次全新的神秘市场将返场稀有度高的道具。全新黑货箱也将在藏匿处出现&#xff0c;工坊也会推出全新工匠通行证。不仅如此&#xff0c;特殊制作中也能看到…

《YOLOv8-Pose关键点检测》专栏介绍 CSDN独家改进创新实战 专栏目录

YOLOv8-Pose关键点检测专栏介绍&#xff1a;http://t.csdnimg.cn/gRW1b ✨✨✨手把手教你从数据标记到生成适合Yolov8-pose的yolo数据集&#xff1b; &#x1f680;&#x1f680;&#x1f680;模型性能提升、pose模式部署能力&#xff1b; &#x1f349;&#x1f349;&#…

【Java】医院云HIS信息管理系统源码:实现检验、检查、心理CT、B超等医技报告查看

云HIS采用主流成熟技术&#xff0c;软件结构简洁、代码规范易阅读&#xff0c;SaaS 应用&#xff0c;全浏览器访问前后端分离&#xff0c;多服务协同&#xff0c;服务可拆分&#xff0c;功能易扩展&#xff1b;支持多样化灵活配置&#xff0c;提取大量公共参数&#xff0c;无需…

Debian或Ubuntu静态交叉编译arm和aarch64

Debian或Ubuntu静态交叉编译arm和aarch64 介绍术语ARM架构前置条件从源代码编译一个简单的C程序configure和make交叉编译关于静态链接和依赖关系使用 musl libc 实现与 configure 和 make 进行交叉编译 ARM 正在获得越来越多的关注&#xff0c;并且越来越受欢迎。直接在这些基于…

知行之桥EDI系统如何连接人大金仓数据库?

近年来受到国际形势与国内发展规划等因素的影响&#xff0c;“国产替代”口号逐渐深入人心&#xff0c;越来越多的企业开始考虑用国产软件替代国外软件&#xff0c;尤其是在当前的大数据时代&#xff0c;计算能力主要依赖于数据中心。 然而&#xff0c;20世纪70年代以来&#…

基于springboot实现原创歌曲分享平台系统项目【项目源码+论文说明】

基于springboot实现原创歌曲分享平台系统演示 摘要 随着信息技术和网络技术的飞速发展&#xff0c;人类已进入全新信息化时代&#xff0c;传统管理技术已无法高效&#xff0c;便捷地管理信息。为了迎合时代需求&#xff0c;优化管理效率&#xff0c;各种各样的管理平台应运而生…

Python3.8引入海象运算符(Walrus Operator)的一些认识

1、引言 这个运算符为什么跟海象联系在一起呢&#xff1f;因为看起来像是躺着的海象&#xff0c;其中眼睛和牙齿的形象表示就是海象运算符了&#xff0c;如下图&#xff1a; 海象运算符&#xff0c;也叫做海象选择器&#xff0c;在Go语言中很常见&#xff0c;Python3.8也开始引…

智能直流自动清洁离子风机的优势和应用

智能直流自动清洁离子风机是一种高效、智能化的通风设备&#xff0c;具有以下优势&#xff1a; 清洁方便&#xff1a;智能直流自动清洁离子风机配备了自动清洁功能&#xff0c;可以自动清洁离子发生器&#xff0c;减少清洁维护的时间和成本。 高效节能&#xff1a;智能直流自动…

2003 - Can‘t connect to MysQL server on ‘39.108.169.0‘ (10060 “Unknown error“)

问题描述 某天和往常一样启动java项目&#xff0c;发现数据库出问题了&#xff0c;然后打开navicat&#xff0c;发现数据库的链接都连接不上&#xff0c; 一点击就会弹出报错框&#xff1a; 然后就各种上网搜索。 解决方案 上网查了一些解决方案&#xff0c;大部分都是说看…

随想录一刷·数组part1

你好&#xff0c;我是安然无虞。 文章目录 1. 二分查找题型2. 移除元素题型 1. 二分查找题型 二分查找传送门 class Solution { public:int search(vector<int>& nums, int target) {// 在有序数组中查找第一时间想到二分查找int left 0, right nums.size() - 1…

似乎我养的这只猫可能正能犯二

真的会有弱智猫吗&#xff1f;请问&#xff0c;我家小猫天天跑酷发疯 然后不停的撞到头还撞的哐哐响&#xff0c;就刚刚五分钟以内她已经撞了七八次头了&#xff0c;我真觉得她有点不聪明。 我刚准备上卫生间&#xff0c;然后扭头看一下它&#xff0c;它看我回过头来然后就赶紧…

【致远】致远OA取消个人空间显示。

【问题需求】 使用致远系统OA软件过程中&#xff0c;由于公司各个部门有对应的空间布局。 所以想要各个部门人员登陆后&#xff0c;默认对应部门空间。 但是所有人登录后&#xff0c;都会默认为个人空间。 虽然在首页设置–导航设置中&#xff0c;可以将个人空间取消显示&#…

5个最流行的文本生成纹理AI工具

在线工具推荐&#xff1a; Three.js AI纹理开发包 - YOLO合成数据生成器 - GLTF/GLB在线编辑 - 3D模型格式在线转换 - 3D场景编辑器 拥抱文本生成纹理AI模型改变游戏规则的力量&#xff0c;人工智能驱动的创新彻底改变了游戏开发中的资产创建。 这些出色的工具可将书面描述转换…

数据抽样技术全面概述

抽样是研究和数据收集中不可或缺的方法&#xff0c;能够从更大数据中获得有意义的见解并做出明智的决定的子集。不同的研究领域采用了不同的抽样技术&#xff0c;每种技术都有其独特的优点和局限性。本文将深入探讨了最常见的抽样技术&#xff0c;包括随机抽样、分层抽样、系统…

界面控件DevExtreme v23.1新版亮点 - 数据层、可访问性功能升级

DevExtreme拥有高性能的HTML5 / JavaScript小部件集合&#xff0c;使您可以利用现代Web开发堆栈&#xff08;包括React&#xff0c;Angular&#xff0c;ASP.NET Core&#xff0c;jQuery&#xff0c;Knockout等&#xff09;构建交互式的Web应用程序。从Angular和Reac&#xff0c…

【Servlet】 一

本文主要介绍了如何在tomcat部署一个webapp 以及 如何借助maven用servlet编写一个hello world . 一.Tomcat Tomcat是一个Java里广泛使用的http服务器 HTTP服务器有很多实现&#xff0c;其中最知名的是Nginx&#xff1b;而在Java里&#xff0c;最知名的是Tomcat 一个Tomcat服务…

mysql数据库【基础】

本教程适合有一定基础的人&#xff0c;我是用来复习mysql数据&#xff0c;跟着教程走一遍熟悉一下mysql的语句 数据准备 下面的数据库查询语句都是基于此表进行查询的 员工表 创建表&#xff1a; -- 创建表 drop table if exists emp; create table emp (id int …