Java Stream API:让集合操作更优雅的利器

news2024/11/26 14:25:06

前言

A sequence of elements supporting sequential and parallel aggregate operations.

Java 8引入的Stream API是一种处理集合数据的高级抽象,它允许以声明式的方式对集合进行操作,使得代码更加简洁和易读。Stream不是数据结构,它不会存储数据,而是对数据源(如集合、数组等)进行一系列的操作,并返回一个新的Stream或一个最终结果。

Stream操作可以分为中间操作(Intermediate Operations)和终端操作(Terminal Operations)。中间操作会返回一个新的Stream,所以可以链式调用多个中间操作,如filtermap等;终端操作会触发Stream的执行并返回一个非Stream的结果,如forEachreduce等。

基本语法

image

  • 创建Stream;
  • 转换Stream,每次转换原有Stream对象不改变,返回一个新的Stream对象
  • 对Stream进行聚合(Reduce)操作,获取想要的结果;

创建Stream

从集合创建

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;

public class StreamDemo {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("apple");
        list.add("banana");
        list.add("cherry");
        Stream<String> stream = list.stream();
        stream.forEach(System.out::println);
    }
}

首先创建了一个ArrayList,添加了三个水果名称。然后通过list.stream()方法创建了一个Stream对象,最后使用forEach终端操作来遍历并打印出每个元素。

从数组创建

import java.util.Arrays;
import java.util.stream.Stream;

public class StreamDemo {
    public static void main(String[] args) {
        String[] array = {"apple", "banana", "cherry"};
        Stream<String> stream = Arrays.stream(array);
        stream.forEach(System.out::println);
    }
}

定义了一个字符串数组,然后使用Arrays.stream(array)方法将数组转换为Stream,再通过forEach打印每个元素。

中间操作 - filter

用于过滤Stream中的元素,只保留满足指定条件的元素。

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;

public class StreamDemo {
    public static void main(String[] args) {
        List<Integer> numbers = new ArrayList<>();
        numbers.add(1);
        numbers.add(2);
        numbers.add(3);
        numbers.add(4);
        numbers.add(5);
        Stream<Integer> stream = numbers.stream().filter(n -> n % 2 == 0);
        stream.forEach(System.out::println);
    }
}

创建了一个包含整数的ArrayList,然后通过stream().filter(n -> n % 2 == 0)操作,只保留能被2整除的元素,最后使用forEach打印出这些元素,这里会输出2和4。

中间操作 - map

map方法示意图
image

对Stream中的每个元素应用一个函数,将其转换为另一个元素。

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;

public class StreamDemo {
    public static void main(String[] args) {
        List<String> fruits = new ArrayList<>();
        fruits.add("apple");
        fruits.add("banana");
        fruits.add("cherry");
        Stream<String> stream = fruits.stream().map(fruit -> fruit.toUpperCase());
        stream.forEach(System.out::println);
    }
}

创建了水果名称的列表,通过stream().map(fruit -> fruit.toUpperCase())操作将每个水果名称转换为大写形式,最后使用forEach打印出来,会输出APPLE、BANANA、CHERRY。

终端操作 - reduce

将Stream中的元素组合起来,得到一个单一的结果。

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;

public class StreamDemo {
    public static void main(String[] args) {
        List<Integer> numbers = new ArrayList<>();
        numbers.add(1);
        numbers.add(2);
        numbers.add(3);
        numbers.add(4);
        numbers.add(5);
        int sum = numbers.stream().reduce(0, (a, b) -> a + b);
        System.out.println("Sum: " + sum);
    }
}

创建整数列表,通过reduce(0, (a, b) -> a + b)操作,从初始值0开始,将每个元素相加。这里会计算列表中所有整数的和,最后打印出总和,结果为15。

排序操作 - sorted

用于对Stream中的元素进行排序。可以根据元素的自然顺序(如果元素实现了Comparable接口)进行排序,也可以通过自定义比较器(Comparator)来指定排序规则。

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;

public class StreamDemo {
    public static void main(String[] args) {
        List<Integer> numbers = new ArrayList<>();
        numbers.add(3);
        numbers.add(1);
        numbers.add(4);
        numbers.add(2);
        Stream<Integer> stream = numbers.stream().sorted();
        stream.forEach(System.out::println);
    }
}
  • 代码解释:首先创建了一个包含整数的ArrayList,元素顺序是无序的。然后使用stream().sorted()操作,按照整数的自然顺序(从小到大)对元素进行排序,最后通过forEach打印出排序后的元素,输出结果为1、2、3、4。

自定义比较器排序

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Stream;

public class StreamDemo {
    public static void main(String[] args) {
    List<String> fruits = new ArrayList<>();
        fruits.add("apple");
        fruits.add("banana");
        fruits.add("cherry");
        Stream<String> stream = fruits.stream().sorted(Comparator.comparing(String::length));
        stream.forEach(System.out::println);
    }
}

创建了一个水果名称列表,通过stream().sorted(Comparator.comparing(String::length))操作,根据字符串的长度对水果名称进行排序。在这里,先输出长度较短的单词,即apple,然后是cherry,最后是banana

去重操作 - distinct

用于去除Stream中的重复元素。它会根据元素的equals方法来判断元素是否相同。

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;

public class StreamDemo {
    public static void main(String[] args) {
        List<Integer> numbers = new ArrayList<>();
        numbers.add(1);
        numbers.add(2);
        numbers.add(1);
        numbers.add(3);
        numbers.add(2);
        Stream<Integer> stream = numbers.stream().distinct();
        stream.forEach(System.out::println);
    }
}

创建包含整数的ArrayList,其中有重复的元素。使用stream().distinct()操作去除重复元素后,通过forEach打印出结果,输出为1、2、3。

收集操作 - collect

用于将Stream中的元素收集到一个集合(如ListSetMap等)或者其他数据结构中。这是一个终端操作,它会终止Stream并返回收集后的结果。

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class StreamDemo {
    public static void main(String[] args) {
        List<Integer> numbers = new ArrayList<>();
        numbers.add(1);
        numbers.add(2);
        numbers.add(3);
        List<Integer> collectedList = numbers.stream().collect(Collectors.toList());
        System.out.println(collectedList);
    }
}

创建一个整数ArrayList,然后使用stream().collect(Collectors.toList())操作将Stream中的元素收集到一个新的List中,并打印这个新的List,输出为[1, 2, 3]

资料

  • https://blogs.oracle.com/javamagazine/post/java-quiz-streams-collections-dropwhile-takewhile
  • https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/stream/Stream.html
  • https://dev.java/learn/api/streams/

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

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

相关文章

【WiFi7】 支持wifi7的手机

数据来源 Smartphones with WiFi 7 - list of all latest phones 2024 Motorola Moto X50 Ultra 6.7" 1220x2712 Snapdragon 8s Gen 3 16GB RAM 1024 GB 4500 mAh a/b/g/n/ac/6e/7 Sony Xperia 1 VI 6.5" 1080x2340 Snapdragon 8 Gen 3 12GB RAM 512 G…

基于Springboot+Vue的宾馆客房管理系统设计与实现(含源码数据库)

1.开发环境 开发系统:Windows10/11 架构模式:MVC/前后端分离 JDK版本: Java JDK1.8 开发工具:IDEA 数据库版本: mysql5.7或8.0 数据库可视化工具: navicat 服务器: SpringBoot自带 apache tomcat 主要技术: Java,Springboot,mybatis,mysql,vue 2.视频演示地址 3.功能 该系统…

Vue 3 和 Vue Router 使用 createWebHistory 配置

在 Vue 3 项目中&#xff0c;如果使用 Vue Router 并希望启用 HTML5 History 模式&#xff0c;需要在创建路由器实例时传入 createWebHistory 作为历史模式的配置。此外&#xff0c;还需要确保在生产环境中设置正确的基本路径&#xff08;base&#xff09;&#xff0c;这样才能…

QT笔记00 记事本项目

QT GUI编程-CSDN博客 00&#xff1a;按键,对话框,垂直布局 包含内容: 按键,对话框,垂直布局的创建 #include <QPushButton> #include <QVBoxLayout> //普通按钮 QPushButton *bt_test; //普通按钮示例 bt_test new QPushButton("ok"); bt_test-&g…

Web应用框架-Django应用基础(2)

1.请求响应对象 1.1 请求对象HttpRequest测试 #hello\views def http_request(request):#1.获得请求方式print(request.method)#2.获得请求头信息#2.1 获取META中的请求头信息headers request.METAprint(headers)#2.2 获取请求头信息的内容ua request.META.get(HTTP_USER_AG…

PHP露营地管理小程序系统源码

&#x1f3d5;️露营新风尚&#xff01;露营地管理小程序系统&#xff0c;打造完美露营体验✨ &#x1f4cd;营地预订&#xff0c;轻松搞定&#x1f4c5; 想要逃离城市的喧嚣&#xff0c;享受大自然的宁静&#xff1f;露营地管理小程序系统让你的露营计划轻松实现&#xff01…

1 -《本地部署开源大模型》如何选择合适的硬件配置

如何选择合适的硬件配置 为了在本地有效部署和使用开源大模型&#xff0c;深入理解硬件与软件的需求至关重要。在硬件需求方面&#xff0c;关键是配置一台或多台高性能的个人计算机系统或租用配备了先进GPU的在线服务器&#xff0c;确保有足够的内存和存储空间来处理大数据和复…

后备电池、蓄电池在线监测系统-安科瑞黄安南

电池相关的概念 电池分类&#xff1a;后备电池、储能电池、动力电池 电池参数&#xff1a;电压、温度、内阻、充放电电流、SOC、SOH 行业背景 电池失效主要原因一 电池失效主要原因二 几乎所有的蓄电池故障都可以通过单体内阻增加检测出来。 内阻与容量的关系 内阻值横向比较 …

企业文件防泄密软件推荐|2024年8款好用的企业防泄密软件排行榜

在信息化时代&#xff0c;企业的数据安全越来越重要&#xff0c;防止敏感信息泄露成为了每个企业必须面对的挑战。为了有效保护企业文件、数据和知识产权&#xff0c;许多企业选择部署防泄密&#xff08;DLP&#xff0c;Data Loss Prevention&#xff09;软件。这些工具不仅可以…

MR30 IO模块——助力污水处理厂高效运营

在环境保护日益受到重视的今天&#xff0c;污水处理厂作为水资源循环利用的重要环节&#xff0c;其运营效率和处理效果直接关系到水资源的可持续利用和生态环境保护。然而&#xff0c;传统水处理设施普遍面临自动化程度低、管理难度大、能耗高、故障率高等问题&#xff0c;严重…

期权懂|期权市场中看涨期权合约的盈利怎么算?

本期让我懂 你就懂的期权懂带大家来了解&#xff0c;股票下跌时可以使用期权止损吗&#xff1f;有兴趣的朋友可以看一下。期权小懂每日分享期权知识&#xff0c;帮助期权新手及时有效地掌握即市趋势与新资讯&#xff01; 期权市场中看涨期权合约的盈利怎么算&#xff1f; 看涨期…

C++学习实例:入门,了解其输入输出

1、字母转换—题目描述 输入一个小写字母&#xff0c;输出其对应的大写字母。例如输入 q[回车] 时&#xff0c;会输出 Q。 输入格式 无 输出格式 无 输入输出样例 输入 #1 q 输出 #1 Q #include<bits/stdc.h> #include<cctype> using namespace std; in…

蘑菇分类识别数据集(猫脸码客 第222期)

蘑菇分类识别文本/图像数据集 蘑菇&#xff0c;作为一种广泛分布于全球的真菌&#xff0c;隶属于伞菌目伞菌亚门蘑菇科蘑菇属&#xff0c;拥有众多别名&#xff0c;如白蘑菇、洋蘑菇等。其不仅是世界上人工栽培最广泛、产量最高、消费量最大的食用菌品种之一&#xff0c;还在许…

International Symposium on Artificial Intelligence Innovations

计算机科学&#xff08;Computer Science&#xff09;&#xff1a; 算法、自动化软件工程、生物信息学和科学计算、计算机辅助设计、计算机动画、计算机体系结构、计算机建模、计算机网络、计算机安全、计算机图形学与图像处理、数据库与数据挖掘、数据压缩、数据加密、数字信号…

【渗透测试】-红日靶场-获取web服务器权限

拓扑图&#xff1a; 前置环境配置&#xff1a; Win 7 默认密码&#xff1a;hongrisec201 内网ip:192.168.52.143 打开虚拟网络编辑器 添加网络->VMent1->仅主机模式->子网ip:192.168.145.0 添加网卡&#xff1a; 虚拟机->设置-> 添加->网络适配器 保存&a…

C++ —— set系列的使用

目录 1. 序列式容器和关联式容器 2. set和multiset参考⽂档 3. set类的介绍 4. set的构造和迭代器 4.1 set的增删查 4.1.1 插入 4.1.2 查找 4.1.3 删除 5. multiset和set的差异 1. 序列式容器和关联式容器 前⾯我们已经接触过STL中的部分容器如&#xff1a;str…

【数据库设计】逻辑结构设计

E-R实体集的转换 概念结构设计之后就是对E-R图进行逻辑结构设计&#xff1a;即将E-R图转化成关系的过程。逻辑结构设计主要用于数据库管理系统上&#xff0c;为了让数据在计算机系统中更好地表示。 此设计过程用到的数据模型有&#xff1a;除了前面讲过的关系模型还有层次模型…

如何看一个flutter项目的具体flutter版本

查看pubspec.lock文件 这个项目实际运行的就是 flutter 3.16.6 版本的

详解Java之Spring MVC篇一

目录 Spring MVC 官方介绍 MVC RequestMapping 传递参数 无参数 单个参数 针对String类型 针对Integer类型 针对int类型 针对自定义类型 多个参数 参数重命名 参数强制一致 参数不强制一致 传递数组 ​编辑传递List ​编辑 传递JSON ​编辑 从路径中获取参…

你们想要的格姗导航网站终于开源了!

关注小格子的读者们&#xff0c;应该都知道&#xff0c;小格子自己做了一个导航网站。 通过这几天的代码和文档整理&#xff0c;决定把导航网站给大家开源。目前只开源基础版&#xff0c;大家可以根据此开源项目开发自定义导航。 格姗导航网站 一个基于 Spring Boot、MyBati…