当前位置: 首页 > article >正文

学习笔记083——Java Stream API

文章目录

  • 1、过滤数据 filter()
  • 2、转换元素 map()
  • 3、排序 sorted()
    • 3.1、自定义排序规则
  • 4、去重 distinct()
  • 5、限制元素数量 limit()
  • 6、收集结果 collect()
    • 6.1、收集为List
    • 6.2、收集为Set
    • 6.3、转为Map
    • 6.4、基本用法(注意键冲突会抛异常)
    • 6.5、处理键冲突(例如,取后出现的值)
    • 6.6、指定 Map 实现类
    • 6.7、将对象自身作为值
    • 6.8、统计总和
    • 6.9、字符串拼接
  • 7、遍历元素
  • 8、匹配检查
  • 9、分组 Grouping By
  • 10、聚合操作 reduce()
  • 11、统计
  • 12、跳过元素 skip()

1、过滤数据 filter()

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);List<Integer> numberFilter = numbers.stream().filter(n -> n % 2 == 0) // 过滤偶数.collect(Collectors.toList()); // [2, 4]

2、转换元素 map()

List<String> words = Arrays.asList("apple", "banana");List<Integer> lengths = words.stream().map(String::length) // 转换为单词长度.collect(Collectors.toList()); // [5, 6]

3、排序 sorted()

List<String> list = Arrays.asList("a", "b", "c");List<String> sortedList = list.stream().sorted() // 自然排序(字典序).collect(Collectors.toList());// [a, b, c]

3.1、自定义排序规则

List<Integer> nums = Arrays.asList(3, 1, 4);List<Integer> customSorted = nums.stream().sorted((a, b) -> b - a) // 降序排序.collect(Collectors.toList()); // [4, 3, 1]

4、去重 distinct()

List<Integer> num2 = Arrays.asList(1, 2, 2, 3);List<Integer> unique = num2.stream().distinct() // 去重.collect(Collectors.toList()); // [1, 2, 3]

5、限制元素数量 limit()

List<Integer> number2 = Arrays.asList(1, 2, 3, 4, 5);List<Integer> firstThree = number2.stream().limit(3) // 取前3个元素.collect(Collectors.toList()); // [1, 2, 3]

6、收集结果 collect()

6.1、收集为List

List<String> list3 = Arrays.asList("a", "b", "ac", "d", "a", "c");List<String> filteredList = list3.stream().filter(s -> s.startsWith("a")).collect(Collectors.toList()); // 收集为List  过滤出以a开头的  [a, ac, a]

6.2、收集为Set

Set<String> set = list3.stream().collect(Collectors.toSet()); // 收集为Set  去重  [a, b, ac, c, d]

6.3、转为Map

Map<String, Integer> map = set.stream().collect(Collectors.toMap(s -> s, String::length)); // 转为Map   每个元素的长度  {a=1, ac=2, b=1, c=1, d=1}

6.4、基本用法(注意键冲突会抛异常)

实体类

@Data
public class Employee {//部门private String dept;//姓名private String name;//薪水private int salary;public Employee(String dept, String name) {this.dept = dept;this.name = name;}public Employee(String dept, String name, int salary) {this.dept = dept;this.name = name;this.salary = salary;}
}
List<Employee> employeeList = new ArrayList<>();
employeeList.add(new Employee("1", "张三", 6000));
employeeList.add(new Employee("2", "李四", 6000));
employeeList.add(new Employee("3", "王五", 6000));Map<String, Integer> map2 = employeeList.stream().collect(Collectors.toMap(Employee::getDept,   // 键的提取函数Employee::getSalary  // 值的提取函数)
);
//{1=6000, 2=6000, 3=6000}

6.5、处理键冲突(例如,取后出现的值)

通过第三个参数(合并函数)解决键冲突:

List<Employee> employeeList = new ArrayList<>();
employeeList.add(new Employee("1", "张三", 6000));
employeeList.add(new Employee("2", "李四", 6000));
employeeList.add(new Employee("3", "王五", 6000));
employeeList.add(new Employee("3", "赵六", 6000));Map<String, String> map3 = employeeList.stream().collect(Collectors.toMap(Employee::getDept,          // 键的提取函数Employee::getName,          // 值的提取函数(oldVal, newVal) -> newVal  // 解决冲突的函数(取新的value))
);
//{1=张三, 2=李四, 3=赵六}

6.6、指定 Map 实现类

/***  指定 Map 实现类*  通过第四个参数自定义 Map 类型(如 LinkedHashMap 保持插入顺序):*/
Map<String, String> idToName = employeeList.stream().collect(Collectors.toMap(Employee::getDept,Employee::getName,(oldVal, newVal) -> newVal,LinkedHashMap::new  // 指定Map实现));
//{1=张三, 2=李四, 3=赵六}

6.7、将对象自身作为值

/*** 将对象自身作为值   (注意键冲突会抛异常)* 使用  Function.identity()  直接引用元素作为值*/
List<Employee> employeeList222 = new ArrayList<>();
employeeList222.add(new Employee("1", "张三", 6000));
employeeList222.add(new Employee("2", "李四", 6000));
employeeList222.add(new Employee("3", "王五", 6000));
Map<String, Employee> idToPerson = employeeList222.stream().collect(Collectors.toMap(Employee::getDept,Function.identity()  // 值=对象本身));
// {
// 1=Employee(dept=1, name=张三, salary=6000),
// 2=Employee(dept=2, name=李四, salary=6000),
// 3=Employee(dept=3, name=王五, salary=6000)
// }

6.8、统计总和

例如部门工资总和

List<Employee> employeeList333 = new ArrayList<>();
employeeList333.add(new Employee("1", "张三", 6000));
employeeList333.add(new Employee("2", "李四", 6000));
employeeList333.add(new Employee("3", "王五", 6000));
employeeList333.add(new Employee("1", "张三1", 7000));
employeeList333.add(new Employee("2", "李四1", 8000));
employeeList333.add(new Employee("3", "王五1", 9000));
Map<String, Integer> deptSalarySum = employeeList333.stream().collect(Collectors.toMap(Employee::getDept,Employee::getSalary,Integer::sum  // 合并时累加工资));
//{1=13000, 2=14000, 3=15000}

6.9、字符串拼接

/**  字符串拼接  */
List<String> str = Arrays.asList("a", "b", "c");
String join1 = str.stream().collect(Collectors.joining());  //abc
String join2 = str.stream().collect(Collectors.joining(", "));  //a, b, c
String join3 = str.stream().collect(Collectors.joining(", ", "[", "]"));    //[a, b, c]

7、遍历元素

List<String> list3 = Arrays.asList("a", "b", "ac", "d", "a", "c");
list3.stream().forEach(System.out::println); // 打印每个元素

8、匹配检查

/***  匹配检查: anyMatch()   allMatch()   noneMatch()*/List<String> list4 = Arrays.asList("a", "b", "c");
boolean hasA = list4.stream().anyMatch(s -> s.contains("a")); // 是否存在包含"a"的元素  trueList<Integer> numbers4 = Arrays.asList(1, 2, 3, 4, 5);
boolean allPositive = numbers4.stream().allMatch(n -> n > 0); // 是否所有元素都大于0     true

9、分组 Grouping By

List<Employee> employees = new ArrayList<>();
employees.add(new Employee("1","张三", 5000));
employees.add(new Employee("1","李四", 5500));
employees.add(new Employee("2","王五", 6000));
employees.add(new Employee("2","赵六", 7000));
employees.add(new Employee("3","韩七", 5800));
employees.add(new Employee("4","魏八", 9000));// 按属性分组(按照部门分组)
Map<String, List<Employee>> groupByDept = employees.stream().collect(Collectors.groupingBy(Employee::getDept));
// {
// 1=[Employee(dept=1, name=张三, salary=5000), Employee(dept=1, name=李四, salary=5500)],
// 2=[Employee(dept=2, name=王五, salary=6000), Employee(dept=2, name=赵六, salary=4000)],
// 3=[Employee(dept=3, name=韩七, salary=5800)],
// 4=[Employee(dept=4, name=魏八, salary=9000)]
// }// 分组后对值进一步处理(如求数量:统计每个部门的人数)
Map<String, Long> countByDept = employees.stream().collect(Collectors.groupingBy(Employee::getDept, Collectors.counting()));
//{1=2, 2=2, 3=1, 4=1}// 多级分组(嵌套分组) 先按照每个部门分组,然后按照薪水是否超过5000分组
Map<String, Map<Boolean, List<Employee>>> multiGroup = employees.stream().collect(Collectors.groupingBy(Employee::getDept,Collectors.groupingBy(e -> e.getSalary() > 5000)));
// {
// 1={false=[Employee(dept=1, name=张三, salary=5000)], true=[Employee(dept=1, name=李四, salary=5500)]},
// 2={true=[Employee(dept=2, name=王五, salary=6000), Employee(dept=2, name=赵六, salary=7000)]},
// 3={true=[Employee(dept=3, name=韩七, salary=5800)]},
// 4={true=[Employee(dept=4, name=魏八, salary=9000)]}
// }

10、聚合操作 reduce()

List<Integer> numbers5 = Arrays.asList(1, 2, 3, 4, 5);
Optional<Integer> sum = numbers5.stream().reduce((a, b) -> a + b); // 求和(返回Optional)   Optional[15]int total = numbers5.stream().reduce(0, Integer::sum); // 初始值为0的求和   15

11、统计

/*** 统计: count()   min()   max()*/List<String> list5 = Arrays.asList("a", "b", "c");
long count = list5.stream().count(); // 元素总数  3List<Integer> numbers6 = Arrays.asList(1, 2, 3, 4, 5);
Optional<Integer> max = numbers6.stream().max(Integer::compare); // 最大值  Optional[5]
Optional<Integer> min = numbers6.stream().min(Integer::compare); // 最小值  Optional[1]

12、跳过元素 skip()

List<Integer> numbers7 = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> skipped = numbers7.stream().skip(2) // 跳过前2个元素.collect(Collectors.toList()); //[3, 4, 5]

相关文章:

学习笔记083——Java Stream API

文章目录 1、过滤数据 filter()2、转换元素 map()3、排序 sorted()3.1、自定义排序规则 4、去重 distinct()5、限制元素数量 limit()6、收集结果 collect()6.1、收集为List6.2、收集为Set6.3、转为Map6.4、基本用法&#xff08;注意键冲突会抛异常&#xff09;6.5、处理键冲突&…...

DataEase同比环比

DataEase同比环比 前言术语实现表结构设计DataEase设计创建数据集创建仪表盘最后前言 某大数据项目,需要比较展示今年跟去年的数据,如下图: 说明:比较24,25的产品销量,相同月份做一组,并排放一块 还有更进一步: 说明:比较24,25相同月份,相同产品的销量 直接用DataE…...

RAG 工程基础

RAG 概念 RAG&#xff08;Retrieval - Augmented Generation&#xff09;技术是一种将检索与生成相结合的人工智能技术&#xff0c;旨在利用外部知识源来增强语言模型的生成能力&#xff0c;提高生成内容的质量、准确性和相关性。 具体来说&#xff0c;RAG 技术在处理用户输入的…...

基础算法:滑动窗口_python版本

能使用滑动窗口的题&#xff0c;基本都需要数字为正整数&#xff0c;这样才能保证滑入一个数字总和是增加的(单调性) 一、209. 长度最小的子数组 思路&#xff1a; 已每个位置为右端点&#xff0c;依次加大左端点&#xff0c;最短不满足 sum(num[left,right]) < target的。…...

Qt 之opengl shader language

着色器示例代码 实际运行效果...

PyRoboPlan 库,给 panda 机械臂微分 IK 上大分,关节限位、碰撞全不怕

视频讲解&#xff1a; PyRoboPlan 库&#xff0c;给 panda 机械臂微分 IK 上大分&#xff0c;关节限位、碰撞全不怕 代码仓库&#xff1a;https://github.com/LitchiCheng/mujoco-learning 今天分享PyRoboPlan库&#xff0c;比之前的方式优点在于&#xff0c;这个库考虑了机械…...

GPT - TransformerDecoderBlock

本节代码定义了一个 TransformerDecoderBlock 类&#xff0c;它是 Transformer 架构中解码器的一个基本模块。这个模块包含了多头自注意力&#xff08;Multi-Head Attention&#xff09;、前馈网络&#xff08;Feed-Forward Network, FFN&#xff09;和层归一化&#xff08;Lay…...

LabVIEW 控制电机需注意的关键问题

在自动化控制系统中&#xff0c;LabVIEW 作为图形化编程平台&#xff0c;因其高度可视化、易于集成硬件等优势&#xff0c;被广泛应用于电机控制场景。然而&#xff0c;要实现稳定、精确、高效的电机控制&#xff0c;仅有软件并不足够&#xff0c;还需结合硬件选型、控制逻辑设…...

CSS 定位属性的生动比喻:以排队为例理解 relative 与 absolute

目录 一、理解标准流与队伍的类比 二、relative 定位:队伍中 “小范围活动” 的人 三、absolute 定位:队伍中 “彻底离队” 的人 在学习 CSS 的过程中,定位属性relative和absolute常常让初学者感到困惑。它们的行为方式和对页面布局的影响较为抽象,不过,我们可以通过一个…...

Jenkins 发送钉钉消息

这里不介绍 Jenkins 的安装&#xff0c;可以网上找到很多安装教程&#xff0c;重点介绍如何集成钉钉消息。 需要提前准备钉钉机器人的 webhook 地址。&#xff08;网上找下&#xff0c;很多教程&#xff09; 下面开始配置钉钉机器人&#xff0c;登录 Jenkins&#xff0c;下载 …...

nt!KeRemoveQueue 函数分析之加入队列后进入等待状态

第一部分&#xff1a; 参考例子&#xff1a;应用程序调用kernel32!GetQueuedCompletionStatus后会调用nt!KeRemoveQueue函数进入进入等待状态 0: kd> g Breakpoint 8 hit nt!KiDeliverApc: 80a3c776 55 push ebp 0: kd> kc # 00 nt!KiDeliverApc 01 nt…...

OpenCV 风格迁移

一、引言​ 在计算机视觉和图像处理领域&#xff0c;风格迁移是一项令人着迷的技术。它能够将一幅图像&#xff08;风格图像&#xff09;的艺术风格&#xff0c;如梵高画作的笔触风格、莫奈的色彩风格等&#xff0c;迁移到另一幅图像&#xff08;内容图像&#xff09;上&#x…...

35.Java线程池(线程池概述、线程池的架构、线程池的种类与创建、线程池的底层原理、线程池的工作流程、线程池的拒绝策略、自定义线程池)

一、线程池概述 1、线程池的优势 线程池是一种线程使用模式&#xff0c;线程过多会带来调度开销&#xff0c;进而影响缓存局部性和整体性能&#xff0c;而线程池维护着多个线程&#xff0c;等待着监督管理者分配可并发执行的任务&#xff0c;这避免了在处理短时间任务时创建与…...

Kubernetes nodeName Manual Scheduling practice (K8S节点名称绑定以及手工调度)

Manual Scheduling 在 Kubernetes 中&#xff0c;手动调度框架允许您将 Pod 分配到特定节点&#xff0c;而无需依赖默认调度器。这对于测试、调试或处理特定工作负载非常有用。您可以通过在 Pod 的规范中设置 nodeName 字段来实现手动调度。以下是一个示例&#xff1a; apiVe…...

QML中访问c++数据,并实现类似C#中mvvm模式详细方法

1. 背景需求2. 实现步骤 2.1. 定义 Model&#xff08;数据模型&#xff09; 2.1.1. DataModel.h2.1.2. DataModel.cpp 2.2. 定义 ViewModel&#xff08;视图模型&#xff09; 2.2.1. PersonViewModel.h2.2.2. PersonViewModel.cpp 2.3. 在 QML 中使用 ViewModel 2.3.1. main.cp…...

React 获得dom节点和组件通信

通过REF 实例对象的.current属性获得绑定的DOM节点 组件通信 组件通信 1 父传子 父组件传递数据 子组件接受数据 通过pros对象接受 子组件的形参列表props只读 props中数据不可修改 特殊情况 在子传父的过程中没有直接给子组件添加属性&#xff0c;而是向父组件中添加其他…...

代码,Java Maven项目打包遇到的环境问题

这几天在写一些Java版本的Langchain4J的 AI 测试case&#xff0c;有一段时间不运行的Java环境&#xff0c;反复出现环境问题&#xff0c;记录下 1、Java编译版本的问题 修改编译版本&#xff1a; 2、在IDE中运行遇到Maven中JDK版本问题 在ide中执行maven命令&#xff0c;遇到下…...

fisco-bcos 关于服务bash status.sh启动runing 中但是5002端口监听不到,出错的问题

bash status.sh Server com.webank.webase.front.Application Port 5002 is running PID(4587) yjmyjm-VMware-Virtual-Platform:~/webase-front$ sudo netstat -anlp | grep 5002 没有端口信息输出 此时可以查看log文件夹下的WeBASE-front.log&#xff0c;找到报错信息如下…...

C++ 数据结构之图:从理论到实践

一、图的基本概念 1.1 图的定义与组成 图&#xff08;Graph&#xff09;由顶点&#xff08;Vertex&#xff09;和边&#xff08;Edge&#xff09;组成&#xff0c;形式化定义为&#xff1a; G (V, E) 顶点集合 V&#xff1a;表示实体&#xff08;如城市、用户&#xff09; …...

linux多线(进)程编程——(5)虚拟内存与内存映射

前言&#xff08;前情回顾&#xff09; 进程君开发了管道这门技术后&#xff0c;修真界的各种沟通越来越频繁&#xff0c;这天进程君正与自己的孩子沟通&#xff0c;进程君的孩子说道&#xff1a; “爸爸&#xff0c;昨天我看他们斗法&#xff0c;小明一拳打到了小刚的肚子上&…...

SpringBoot 动态路由菜单 权限系统开发 菜单权限 数据库设计 不同角色对应不同权限

介绍 系统中的路由配置可以根据用户的身份、角色或其他权限信息动态生成&#xff0c;而不是固定在系统中。不同的用户根据其权限会看到不同的路由&#xff0c;访问不同的页面。对应各部门不同的权限。 效果 [{"id": 1,"menuName": "用户管理"…...

[dp8_子数组] 乘积为正数的最长子数组长度 | 等差数列划分 | 最长湍流子数组

目录 1.乘积为正数的最长子数组长度 2.等差数列划分 3.最长湍流子数组 写代码做到&#xff0c;只用维护好自己的一小步 1.乘积为正数的最长子数组长度 链接&#xff1a;1567. 乘积为正数的最长子数组长度 给你一个整数数组 nums &#xff0c;请你求出乘积为正数的最长子数…...

资深词源学家提示词

Role: 资深词源学家 Profile: Language: 中文Description: 作为在词源学领域的卓越专家&#xff0c;具备深厚且多元的学术背景。精通拉丁语、古希腊语、梵语等一众古老语言&#xff0c;能够精准解析这些语言的古代文献&#xff0c;为探寻词汇起源挖掘第一手资料。在汉语研究方…...

深入探讨MySQL存储引擎:选择最适合你的数据库解决方案

前言 大家好&#xff0c;今天我们将详细探讨MySQL中几种主要的存储引擎&#xff0c;了解它们的工作机制、适用场景以及各自的优缺点。通过这篇文章&#xff0c;希望能帮助你根据具体需求选择最合适的存储引擎&#xff0c;优化数据库性能。 1. InnoDB - 默认且强大的事务性存储…...

【图像处理基石】什么是通透感?

一、画面的通透感定义 画面的通透感指图像在色彩鲜明度、空间层次感、物体轮廓清晰度三方面的综合表现&#xff0c;具体表现为&#xff1a; 色彩鲜明&#xff1a;颜色纯净且饱和度适中&#xff0c;无灰暗或浑浊感&#xff1b;层次分明&#xff1a;明暗过渡自然&#xff0c;光…...

无锡无人机超视距驾驶证怎么考?

无锡无人机超视距驾驶证怎么考&#xff1f;在近年来&#xff0c;无人机技术的迅猛发展使得无人机的应用场景变得愈发广泛&#xff0c;其不仅在环境监测、农业喷洒、快递配送等领域展现出真金白银的价值&#xff0c;同时也推动了无人机驾驶证的需求。尤其是在无锡&#xff0c;随…...

213、【图论】有向图的完全联通(Python)

题目描述 原题链接&#xff1a;105. 有向图的完全联通 代码实现 import collectionsn, k list(map(int, input().split())) adjacency collections.defaultdict(list) for _ in range(k):head, tail list(map(int, input().split()))adjacency[head].append(tail)visited_…...

(二十二)安卓开发中的数据存储之SQLite简单使用

在Android开发中&#xff0c;SQLite是一种非常常用的数据库存储方式。它轻量、简单&#xff0c;非常适合移动设备上的数据管理。本文将通过通俗易懂的语言&#xff0c;结合代码示例和具体场景&#xff0c;详细讲解SQLite在Android中的使用。 1. 什么是SQLite? SQLite是一个开…...

图像形态学操作对比(Opencv)

形态学基于图像的形状进行操作&#xff0c;用于处理二值化图像&#xff0c;主要包括腐蚀和膨胀两种基本操作。这些操作通常用于去除噪声、分隔或连接相邻的元素以及寻找图像中显著的最大点和最小点。 1. 形态学操作 import cv2 import numpy as np import matplotlib.pyplot …...

复刻系列-星穹铁道 3.2 版本先行展示页

复刻星穹铁道 3.2 版本先行展示页 0. 视频 手搓&#xff5e;星穹铁道&#xff5e;展示页&#xff5e;&#xff5e;&#xff5e; 1. 基本信息 作者: 啊是特嗷桃系列: 复刻系列官方的网站: 《崩坏&#xff1a;星穹铁道》3.2版本「走过安眠地的花丛」专题展示页现已上线复刻的网…...