逸学java【初级菜鸟篇】9.3 Stream流

hi,我是逸尘,一起学java吧


得益于Lambda所带来的函数式编程,引入了一个全新的Stream流概念(就是都基本使用lambda的形式)。

流处理

我们首先理解什么是流处理,它类似于sql语句,可以执行非常复杂的过滤,映射,查找,收集等功能,且代码很少,但是可读性不高。字如其名,它的处理如同流淌的水一样,或者可以理解为流水线一样。

Stream流

Stream流也是流处理的一种,大多数流处理都是在Stream接口处理的,它是一个泛接口,所以它可以操作的元素是任意对象,他的操作可以用lambda去书写(推荐)。

生成Stream流

Stream操作集合和数组的第一步是得到(生成)Stream流。

在Collection接口默认方法是stream()生成流。

 在数组中使用Arrays.stream(数组) /或Stream.of(数组);

 中间操作方法

其次我们就可以使用中间操作来处理这些元素对象。

这里举出一些常见的API

  • forEach : 逐一处理(遍历)
  • count:统计个数
  • filter : 过滤元素 【数据过滤】
  • distinct:去除重复元素 【数据过滤】
  • limit : 取前几个元素 【数据过滤】
  • skip : 跳过前几个 【数据过滤】
  • map : 加工方法 【数据映射】
  • allMatch:判断流中的元素是否会全部符合某一个条件 【数据查找】
  • concat:合并流

终结操作方法

终结操作方法调用以后流就无法使用了它是流的最后一个过程。

常见的有API有

单独保存的操作方法

  • collect() 方法配合collectors类将流的结果进行保存

处了stream流本身的方法我们还有两个可以协助流操作的类

Collectors类

collectors是一个收集器类,可以将Stream流对象进行封装,归集,分组,是数据的收集,筛选出特殊的数据,可以复杂的统计。

1.toList()将流元素封装到List集合 toSet() toMap()类似

2.toCollection(Supplier<C> collectionFactory) 将流中的元素收集到指定类型的集合中的方法

即一个类型为 Supplier<C> 的函数式接口,其中 C 是要创建的集合类型。例如,如果我们想要创建一个 LinkedList 集合,可以这样使用该方法: 

List<Integer> list = Stream.of(1, 2, 3, 4, 5).collect(Collectors.toCollection(LinkedList::new));

3.groupingBy(Function<? super T, ? extends K> classifier) 

  • 一个函数式接口 classifier,表示如何对流中的元素进行分类。

例如,我们有一个字符串列表,并希望按照字符串长度分组:

List<String> list = Arrays.asList("apple", "banana", "peach", "grape","pear");
Map<Integer, List<String>> map = list.stream().collect(Collectors.groupingBy(String::length));

 在上面的代码中,我们使用 String::length 函数式接口将字符串转换为它的长度,并将其作为分类键。运行结果如下:

{4=[pear], 5=[apple, peach,grape], 6=[banana]}

需要注意的是,groupingBy() 方法返回的是一个 Map 对象,其中键是分类键.

Collectors.groupingBy() 方法还提供了第二个参数 downstream,用于进一步对分组的结果进行处理。例如,我们可以使用 Collectors.counting() 方法统计每个分组中元素的数量:

Map<Integer, Long> map = list.stream().collect(Collectors.groupingBy(String::length, Collectors.counting()));

上面的代码中,我们使用 Collectors.counting() 方法作为 downstream 参数,统计了每个分组中元素的数量,并将结果封装为 Long 类型。运行结果如下:

{4=1, 5=3, 6=1}

4.toConcurrentMap

将流中的元素收集到一个并发 Map 中的方法

ConcurrentMap<Integer, String> concurrentMap = Stream.of("a", "b", "c").collect(Collectors.toConcurrentMap(String::length,Function.identity()));

在上面的例子中,我们使用 toConcurrentMap() 方法创建了一个并发 Map,它将字符串的长度作为键,字符串本身作为值。具体来说,这个方法接受两个参数:

一个函数式接口 keyMapper,表示如何将流中的元素转换成键;
一个函数式接口 valueMapper,表示如何将流中的元素转换成值。
对于上述例子中的流,String::length 函数式接口将字符串转换成它的长度,而 Function.identity() 函数式接口则将字符串映射成它本身。因此得到的结果为:

{1=a, 2=b, 3=c}

 5.以及averagingDouble计算元素平均值,maxBy返回符合条件的最大值,joining()按顺序将元素连接成一个String类型数据,counting()统计个数等等

optional类

这是一个容器类

它的主要功能是针对NullpointerException空指针异常做处理,可以保证保存的值不为null。

of()返回一个value值等于参数的optional实例

ofNullable()是返回一个value值等于非null参数的optional实例

filter()是给定条件值匹配

empty()是静态方法,返回一个空值的optional实例

案例 

我们上面的中间操作,其实是对我们的数据源进行加工。

这里我们简单做了一个去重        

package com.yd.yc;import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;public class Thirteen {public static void main(String[] args) {List<Integer> list = Arrays.asList(6,88,4,5,22,22,6,66,7);//原数据printeach(list);//获取stream,去重,收集器类重新封装List<Integer> collect = list.stream().distinct().collect(Collectors.toList());printeach(collect);}//遍历方法private static void printeach(List<Integer> list) {System.out.println("集合内容"+list);//逐一处理(遍历)里面是lambdalist.stream().forEach(n-> System.out.println(n+""));}
}

某个公司的部门,分为开财务部门和开发部门,现在需要进行月中数据结算。

创建一张员工

部门姓名年龄月工资性别
开发部张三2815000
开发部李四3520000
开发部王五2918000
财务部赵六3316000
财务部刘七3017000
财务部陈八2714000

对应的是我们的员工实体类

public class Employee {  private String name;  private int age;  private double monthlySalary;  private String gender;  private String department;  public Employee(String name, int age, double monthlySalary, String gender, String department) {  this.name = name;  this.age = age;  this.monthlySalary = monthlySalary;  this.gender = gender;  this.department = department;  }  public String getName() {  return name;  }  public int getAge() {  return age;  }  public double getMonthlySalary() {  return monthlySalary;  }  public String getGender() {  return gender;  }  public String getDepartment() {  return department;  }  
}

分别筛选出2个部门的最高工资的员工信息,封装成优秀员工对象topperformer

方案A

package com.yd.yc;import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;public class EmployeeTest {public static void main(String[] args) {Employee employee1 = new Employee("张三", 28, 15000, "男", "开发部");Employee employee2 = new Employee("李四", 35, 20000, "女", "开发部");Employee employee3 = new Employee("王五", 29, 18000, "男", "开发部");Employee employee4 = new Employee("赵六", 33, 16000, "女", "财务部");Employee employee5 = new Employee("刘七", 30, 17000, "男", "财务部");Employee employee6 = new Employee("陈八", 27, 44000, "女", "财务部");//测试//System.out.println(employee1.getName());  // 输出:张三//System.out.println(employee2.getMonthlySalary());  // 输出:20000.0ArrayList<Employee> employeeList = new ArrayList<>();employeeList.add(employee1);employeeList.add(employee2);employeeList.add(employee3);employeeList.add(employee4);employeeList.add(employee5);employeeList.add(employee6);//A方案//filter是过滤找到符合条件的元素//Collectors.maxBy去返回符合条件的最大值,Comparator.comparing(param),param : 这个参数是Function函数式对象,默认大,Comparator.reverseOrder()默认倒序Optional<Employee> result = employeeList.stream().filter(e -> "开发部".equals(e.getDepartment())).collect(Collectors.maxBy(Comparator.comparing(Employee::getMonthlySalary)));//返回一个实体类对象Employee employee = result.get();System.out.println(employee.getName());//第二种写法Employee  resultOne= employeeList.stream().filter(e -> "财务部".equals(e.getDepartment())).max((o1, o2) -> Double.compare(o1.getMonthlySalary(), o2.getMonthlySalary())).get();//必须重写toString才可以有内容System.out.println(resultOne);System.out.println(resultOne.getMonthlySalary());//包装在一个优秀员工里List<Employee> topEmployees = new ArrayList<>();topEmployees.add(resultOne);topEmployees.add(employee);System.out.println(topEmployees);}
}

 方案B

        //B方案Map<String, List<Employee>> groupedByDepartment = employeeList.stream()//分组.collect(Collectors.groupingBy(Employee::getDepartment));List<Employee> topEmployees = new ArrayList<>();for (List<Employee> departmentEmployees : groupedByDepartment.values()) {Employee topEmployee = departmentEmployees.stream().max(Comparator.comparingDouble(Employee::getMonthlySalary))//注意,如果一个部门没有员工,那么这个方法将返回null//该方法在给定的流中找不到元素时返回一个默认值。.orElse(null);if (topEmployee != null) {topEmployees.add(topEmployee);}}System.out.println(topEmployees);

我们要注意的是stream流是方便操作集合/数组的手段,集合/数组才是开发中的目的。

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

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

相关文章

【开源】基于Vue和SpringBoot的智能教学资源库系统

项目编号&#xff1a; S 050 &#xff0c;文末获取源码。 \color{red}{项目编号&#xff1a;S050&#xff0c;文末获取源码。} 项目编号&#xff1a;S050&#xff0c;文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 课程档案模块2.3 课…

原理Redis-SkipList

SkipList ZipList和QuickList的共同特点是节省内存。在遍历元素时&#xff0c;只能从头到尾或从尾到头&#xff0c;所以在查找头尾元素性能还是不错的&#xff0c;但是中间元素查询的性能就会差。 **SkipList&#xff08;跳表&#xff09;**首先是链表&#xff0c;但与传统链表…

【算法】链表-20231123

这里写目录标题 一、19. 删除链表的倒数第 N 个结点二、21. 合并两个有序链表三、24. 两两交换链表中的节点 一、19. 删除链表的倒数第 N 个结点 提示 中等 给你一个链表&#xff0c;删除链表的倒数第 n 个结点&#xff0c;并且返回链表的头结点。 输入&#xff1a;head [1,…

在PyCharm中正确设置Python项目

大家好&#xff0c;在Mac和Linux都支持Python&#xff0c;但许多开发者发现正确设置Python项目很困难。本文汇总了多平台中运行Python的方法&#xff0c;提高编程的效率&#xff0c;如下所示&#xff1a; 使用命令行运行Python。 在PyCharm&#xff08;免费社区版&#xff09;…

【技巧】PDF文件如何编辑?

日常办公中我们经常会用到PDF文件&#xff0c;PDF具备很好的兼容性、稳定性及安全性&#xff0c;但却不容易编辑&#xff0c;那PDF要如何编辑呢&#xff1f; 如果打开PDF文件就只是只读的性质&#xff0c;说明文件是在线打开&#xff0c;或者通过PDF阅读器打开的&#xff0c;这…

Navmesh 寻路

用cocos2dx引擎简单实现了一下navmesh的多边形划分&#xff0c;然后基于划分多边形的a*寻路。以及路径拐点优化算法 用cocos主要是方便使用一些渲染接口和定时器。重点是实现的原理。 首先画了一个带有孔洞的多边形 //多边形的顶点数据Vec2(100, 100),Vec2(300, 200),Vec2(50…

高防服务器的工作原理

在当今互联网时代&#xff0c;网络安全问题日益突出&#xff0c;各种网络攻击层出不穷。为了保护企业的网络安全&#xff0c;高防服务器应运而生。那么&#xff0c;你是否了解高防服务器的工作原理呢&#xff1f;下面就让我们一起来探索一下。 高防服务器是一种能够有效抵御各种…

语音识别入门——常用软件及python运用

工具以及使用到的库 ffmpegsoxaudacitypydubscipylibrosapyAudioAnalysisplotly 本文分为两个部分&#xff1a; P1&#xff1a;如何使用ffmpeg和sox处理音频文件 P2&#xff1a;如何编程处理音频文件并执行基本处理 P1 处理语音数据——命令行方式 格式转换 ffmpeg -i video…

shell 脚本循环语句

目录 循环 echo 命令 for 循环次数 for 第二种格式 命令举例 while 脚本举例 双重循环及跳出循环 脚本举例 更改文件和目录的后缀名的脚本 画三角形的脚本 乘法口诀表的脚本 面试例题 补充命令 let 命令 循环 —— 一定要有跳出循环的条件 已知循环的次数 未知…

英语六级范文模板

目录 现象解释 观点选择 问题解决 六级只考议论文&#xff0c;我们将从现象解释&#xff0c;观点选择&#xff0c;问题解决三个角度给出范文&#xff1a; 多次使用的句子&#xff0c;就可以作为模板记下来~~ 现象解释 In the contemporary world, the ability to meet cha…

SQLite3

数据库简介 常用的数据库 大型数据库&#xff1a;Oracle 中型数据库&#xff1a;Server 是微软开发的数据库产品&#xff0c;主要支持 windows 平台。 小型数据库&#xff1a;mySQL 是一个小型关系型数据库管理系统&#xff0c;开放源码 。(嵌入式不需要存储太多数据。) SQL…

Seaborn画图颜色和给定的RGB hex code不一致

使用以下代码画图&#xff1a; import seaborn as sns import matplotlib.pyplot as plt plt.figure(dpi150) x [A,B,C,D] y [164, 86, 126, 53] sns.barplot(xx, yy, color#3a923a) 得到的颜色如下图所示&#xff1a; 这是因为seaborn默认降低了颜色的饱和度&#xff0c;即…

UDP中connect的作用

udpclientNoConnect.c里边的内容如下&#xff1a; #include<stdio.h> #include<stdlib.h> #include<string.h> #include<unistd.h> #include<arpa/inet.h> #include<sys/socket.h> #include <errno.h> #include <syslog.h…

基于 Flink CDC 打造企业级实时数据集成方案

本文整理自Flink数据通道的Flink负责人、Flink CDC开源社区的负责人、Apache Flink社区的PMC成员徐榜江在云栖大会开源大数据专场的分享。本篇内容主要分为四部分&#xff1a; CDC 数据实时集成的挑战Flink CDC 核心技术解读基于 Flink CDC 的企业级实时数据集成方案实时数据集…

独立版求职招聘平台小程序开发

小程序招聘系统开发 我们开发了一款高效、便捷的互联网招聘平台。在这里&#xff0c;可以轻松实现企业入驻、职位发布、在线求职、精准匹配职位和人才&#xff0c;以及参与招聘会等功能。目标是为求职者和企业搭建一个连接彼此的桥梁&#xff0c;帮助您更快地找到满意的工作&…

SpringMVC(五)SpringMVC的视图

SpringMVC中的视图是View接口&#xff0c;视图的作用渲染数据&#xff0c;将模型Model中的数据展示给用户 SpringMVC视图的种类很多&#xff0c;默认有转发视图(InternalResourceView)和重定向视图(RedirectView) 当工程引入jstl的依赖&#xff0c;转发视图会自动转换为JstlV…

深度学习 loss 是nan的可能原因

1 loss 损失值非常大&#xff0c;超过了浮点数的范围&#xff0c;所以表示为overflow 状态下的男。 解决办法&#xff1a; 减小学习率&#xff0c;观察loss值是不是还是nan 在将数据输入模型前&#xff0c;进行恰当的归一化 缩放 2 loss 的计算中存在除以0&#xff0c; log(0…

Java架构师软件架构开发

目录 1 基于架构的软件开发导论2 ABSD架构方法论3 ABSD方法论具体实现4 ABSD金融业案例5 基于特定领域的软件架构开发导论6 DSSA领域分析7 DSSA领域设计和实现8 DSSA国际电商平台架构案例9 架构思维方法论概述10 AT方法论和案例想学习架构师构建流程请跳转:Java架构师系统架构…

Unity UI设计 软件构造实验报告

实验1: 仿真系统的UI主界面设计 1.实验目的 &#xff08;1&#xff09;熟悉Unity中UI界面的设计与编写&#xff1b; &#xff08;2&#xff09;熟悉UI界面中场景转换,UI与场景内容相互关联的方式。 &#xff08;3&#xff09;熟悉Unity中MySQL数据库的操作 2.实验内容 新建…

生成式AI与大语言模型,东软已经准备就绪

伴随着ChatGPT的火爆全球&#xff0c;数以百计的大语言模型也争先恐后地加入了这一战局&#xff0c;掀起了一场轰轰烈烈的“百模大战”。毋庸置疑的是&#xff0c;继方兴未艾的人工智能普及大潮之后&#xff0c;生成式AI与大语言模型正在全球开启新一轮生产力革新的科技浪潮。 …