JDK新特性(Lambda表达式,Stream流)
Lambda表达式:
Lambda 表达式背后的思想是函数式编程(Functional Programming)思想。在传统的面向对象编程中,程序主要由对象和对象之间的交互(方法调用)构成;而在函数式编程中,重点在于函数的应用和组合。
以上就是Lambda表示的背后思想,做为了解即可
主要要看怎么用:
Lambda表达式的格式:
()->{}
() : 重写方法的参数位置
-> : 将参数传递到方法体中
{} : 重写方法的方法体
直接看代码:
public class Test03 {public static void main(String[] args) {ArrayList<Integer> list = new ArrayList<>();list.add(1);list.add(2);list.add(8);list.add(0);list.add(4);Collections.sort(list, new Comparator<Integer>() {@Overridepublic int compare(Integer o1, Integer o2) {return o1-o2;}});System.out.println(list);Collections.sort(list,((o1, o2) -> o1-o2));System.out.println(list);}
}
上面是用Comparator比较器来定义排序规则
下面则是用Lambda表达式
我们对照起来看,就能发现(o1,o2)就是方法的参数 -> 后面就是方法体。
Lambda表达式使用前提:
在使用Lambda表达式之前,我们需要确认必须是函数式接口做为参数传递:
什么是函数式接口?
有且只有一个抽象方法的接口,用@FunctionalInterface去检测
我们可以点击这个Comparator这个方法

还有我们在线程章节经常用的Runnable接口
new Thread(()->System.out.println(Thread.currentThread().getName())).start();

这时候可能有人会想,Lambda表达式既然只能用函数式接口做为参数,那这个不是很鸡肋嘛
难道我要自己去写一个接口,里面专门再只放一个抽象方法,那这不是更麻烦了嘛
反正我刚刚学的时候,我确实是有这样的疑问
后面问了GPT,其实这个lambda表达式大部分应该是和后面的Stream流一起使用的
Stream流:
Stream流中的"流"不是特指"IO流",它是一种"流式编程"(编程方式),可以看做是"流水线"
个人对流的理解:
在我学习了流的大致用法之后,我其实觉得这个流就是一个操作数组和列表的工具类
里面提供了一系列的方法来操作数组和列表
下面介绍一下Stream流的方法:
Stream流的获取:
这个Stream流的获取就是把数组或者列表转化成流
public class Demo02Stream {public static void main(String[] args) {//1.针对集合:Collection中的方法//Stream<E> stream()ArrayList<String> list = new ArrayList<>();list.add("张三");list.add("李四");list.add("王五");Stream<String> stream = list.stream();System.out.println(stream);//2.针对数组:Stream接口中的静态方法://static <T> Stream<T> of(T... values)Stream<String> stream1 = Stream.of("金莲", "三上", "松下");System.out.println(stream1);}
}
常用方法:
-
filter(Predicate):过滤方法,根据指定的条件对元素进行筛选。
-
map(Function):映射方法,将元素按照指定的映射规则进行转换。
-
forEach(Consumer):遍历方法,对流中的每个元素执行指定的操作。
-
collect(Collectors):收集方法,将流中的元素收集到一个集合中。
-
distinct():去除流中的重复元素。
-
limit(long):截取流中的前几个元素。
-
skip(long):跳过流中的前几个元素。
-
count():统计流中元素的个数。
直接上一段代码:
public class Test01 {public static void main(String[] args) {ArrayList<String> list = new ArrayList<>();list.add("张无忌");list.add("张三丰");list.add("张大彪");list.add("吕不韦");list.add("张三");list.add("赵姬");list.add("张翠山");list.add("嫪毐");//1:筛选出姓张的人System.out.println("筛选出姓张的人");list.stream().filter(s -> s.startsWith("张")).forEach(s -> System.out.print(s+" "));//2:筛选出姓张且名字为两个字的人System.out.println();System.out.println("筛选出姓张且名字为两个字的人");list.stream().filter(s -> s.startsWith("张")).filter(s -> s.length()==2).forEach(s -> System.out.print(s+" "));//3:计算列表的个数System.out.println();System.out.println("计算列表的个数");long count = list.stream().count();System.out.println(count);//4:返回流的前n个对象System.out.println();System.out.println("返回流的前2个对象");Stream<String> limit = list.stream().limit(2);limit.forEach(s -> System.out.print(s+" "));//5:跳过Stream流对象中的前n个元素,返回一个新的Stream流对象System.out.println();System.out.println("跳过Stream流对象中的前n个元素,返回一个新的Stream流对象");list.stream().skip(2).forEach(s-> System.out.print(s+" "));//6:两个流合成一个流System.out.println();System.out.println("两个流合成一个流");ArrayList<String> newlist = new ArrayList<>(Collections.nCopies(list.size(), ""));Collections.copy(newlist,list);System.out.println(newlist);Stream.concat(newlist.stream(),list.stream()).forEach(s -> System.out.print(s+" "));//7:转换流中的类型System.out.println();System.out.println("转换流中的类型");Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5, 6);stream.map(Integer -> Integer+"").forEach(s -> System.out.print(s+" "));}
}
下面来一个项目中的稍微复杂一点的代码加深印象:
在学这个JDK新特性这一章的时候,刚好在写伙伴匹配系统
下面这段鱼皮老师写的代码,我那个时候一直看不懂
现在算是能看懂了
这里的userList就是在数据库中查出来的所有用户列表
这里的tagNameList就是前端传过来的标签列表
所以这一段的逻辑就是根据前端传过来的标签列表进行查找有相同标签的用户
return userList.stream().filter(user -> {String tagsStr = user.getTags();Set<String> tempTagNameSet = gson.fromJson(tagsStr, new TypeToken<Set<String>>() {}.getType());tempTagNameSet = Optional.ofNullable(tempTagNameSet).orElse(new HashSet<>());for (String tagName : tagNameList) {if (!tempTagNameSet.contains(tagName)) {return false;}}return true;}).map(this::getSaftyUser).collect(Collectors.toList());
我们来分析一下整体的代码逻辑:
- 将userList转成流对象
- 转成流对象之后再从对应的用户中取出标签,因为我这里将标签定义成了一个String类型所以后面就将这个String转成了JSON格式的数据存到这个Set集合中
- 用了Optional来对这个转换后的集合做了一个判空处理,如果为空,就new一个空集合
- 然后遍历前端传过来的标签列表,如果判断标签列表中有和用户的标签列表不同的元素直接返回false,这样就被流给过滤掉了
- 接着再对符合要求的用户做一个映射:map(this::getSaftyUser),这个就相当于:map(this::getSaftyUser),将当前对象(this)的
getSaftyUser方法应用到 Stream 中的每个元素上,当我们执行完这个filter方法之后,里面的用户就是我们需要的用户了,我们需要对用户进行一个脱敏将一些重要信息隐藏起来。 - 然后再将我们粉装好的流对象转成列表返回即可
如果上面的逻辑有点难,举个例子,因为我自己一开始也想了很久
比如有三个用户ABC
他们的标签分别是
A : Java ,男,大一
B : Python ,男,大二
C : C++ ,女,大三
然后这个时候我们传入的tagNameList是:男,大一
执行流程就是:我们会先将上面的三个用户取出来成一个列表就是userList
然后将这个列表转换成流对象,接着将这个列表中的每一个对象都执行后面Lambda表达式中的操作,有点像遍历一遍这个列表,比如将A用户的标签取出来 Java ,男,大一,封装成一个Set<String>集合,再遍历tagNameList这个列表:男,大一,挨个判断,男是否在这个集合中,在就继续判断大一这个标签是否在这个集合中,在就结束循环,返回true,就把这个A用户装到流中。
相关文章:
JDK新特性(Lambda表达式,Stream流)
Lambda表达式: Lambda 表达式背后的思想是函数式编程(Functional Programming)思想。在传统的面向对象编程中,程序主要由对象和对象之间的交互(方法调用)构成;而在函数式编程中,重点…...
【ARM】MDK-服务器与客户端不同网段内出现卡顿问题
【更多软件使用问题请点击亿道电子官方网站】 1、 文档目标 记录不同网段之间的请求发送情况以及MDK网络版license文件内设置的影响。 2、 问题场景 客户使用很久的MDK网络版,在获取授权时都会出现4-7秒的卡顿,无法对keil进行任何操作,彻底…...
c++树(一)定义,遍历
目录 树的定义 树的基本术语 树的初始起点:我们定义为根 树的层次: 树的定义: 树的性质 性质1: 性质2: 树形结构存储的两种思路 树的遍历模板 树上信息统计方式1-自顶向下统计 树上信息统计方式2-自底向上统…...
YOLOv5和LPRNet的车牌识别系统
车牌识别系统 YOLOv5和LPRNet的车牌识别系统结合了深度学习技术的先进车牌识别解决方案。该系统整合了YOLOv5目标检测框架和LPRNet文本识别模型 1. YOLOv5目标检测框架 YOLO是一种先进的目标检测算法,以其实时性能和高精度闻名。YOLOv5是在前几代基础上进行优化的…...
内容安全(深度行为检测技术、IPS、AV、入侵检测方法)
1、深度行为检测技术 深度行为检测技术:是一种基于深度学习和机器学习的技术,它通过分析用户在网络中的行为模式,识别异常或潜在威胁行为,从而保护网络安全和内容安全 分类: 深度包检测技术(Deep Packet…...
MySQL双主双从实现方式
双主双从(MM-SS) 前言 避免单一主服务器宕机,集群写入能力缺失 从 1 复制 主1 ,从 2 复制 主 2 主 1 复制 主 2,主 2 复制主 1 也就是 主 1 和主 2 互为主从。主1主2互为主从, 是为了以下情景,…...
pico+unity手柄和摄像机控制初级设置
1、摄像头配置 摄像头模式、floor是追踪原点类型(将根据设备检测到地面的高度来计算追踪原点), Device 模式时,为通常理解的 Eye 模式,不会将根据设备检测到地面的高度来计算追踪原点 选择floor时,修改相…...
vxe-grid 实现配置式form搜索条件 form搜索条件框可折叠 配置式table
文章目录 效果图代码 效果图 代码 <template><div class"app-container"><vxe-grid refxGrid v-bind"gridOptions" v-if"tableHeight" :height"tableHeight"><template #billDate"{ data }"><e…...
TS相较于JS有什么优缺点
TypeScript(TS)是JavaScript的一个超集,它添加了静态类型检查和编译时的强大功能,目的是提高代码质量和维护性。相较于JavaScript,TS的主要优点和缺点如下: 优点: 类型安全性:通过…...
【Harmony】SCU暑期实训鸿蒙开发学习日记Day2
目录 Git 参考文章 常用操作 ArkTS的网络编程 Http编程 发送请求 GET POST 处理响应 JSON数据解析 处理响应头 错误处理 Web组件 用生命周期钩子实现登录验证功能 思路 代码示例 解读 纯记录学习日记,杂乱,误点的师傅可以掉了…...
vue3前端开发-执行npm run dev提示报错怎么解决
vue3前端开发-执行npm run dev提示报错怎么解决!今天在本地安装初始化了一个vue3的案例demo。但是当我执行npm run dev想启动它时报错了说,找不到dev。让我检查package.json文件是否包含dev。如下图所示: 实际上,不必惊慌…...
https 单向认证和双向认证
单向认证 单向认证是客户端(通常是浏览器)验证服务器的身份。服务器向客户端提供数字证书,客户端通过验证该证书的真实性来确认与服务器的连接是安全的。 服务器提供证书:服务器向客户端提供一个数字证书,用于验证服务器的身份。客户端验证服务器:客户端验证服务器的证书…...
Python中Selenium 和 keyboard 库的使用
文章目录 一、Selenium基本使用2.等待元素加载常用操作 keyboard基本使用与 Selenium 联合使用 一、Selenium Selenium 是一个用于浏览器自动化的工具。它可以模拟用户与网页的交互,如点击按钮、填写表单、导航页面等。Selenium 支持多种编程语言,包括 …...
网络安全协议系列
目录 一、安全协议的引入 1.TCP/IP协议族中普通协议的安全缺陷 1.信息泄露 2.信息篡改 3.身份伪装 4.行为否认 2.网络安全需求 二、网络安全协议的定义 三、构建网络安全协议所需的组件 1.加密与解密 2.消息摘要 3.消息验证码 4.数字签名 5.密钥管理 1.建立共享…...
.net core appsettings.json 配置 http 无法访问
1、在appsettings.json中配置"urls": "http://0.0.0.0:8188" 2、但是网页无法打开 3、解决办法,在Program.cs增加下列语句 app.UseAntiforgery();...
opencv—常用函数学习_“干货“_11
目录 二九、图像累加 将输入图像累加到累加图像中 (accumulate) 将输入图像加权累加到累加图像中 (accumulateWeighted) 将输入图像的平方累加到累加图像中 (accumulateSquare) 将两个输入图像的乘积累加到累加图像中 (accumulateProduct) 解释 三十、随机数与添加噪声 …...
WSL-Ubuntu20.04部署环境配置
1.更换Ubuntu软件仓库镜像源 为了在WSL上使用TensorRT进行推理加速,需要安装以下环境,下面将按以下顺序分别介绍安装、验证以及删除环境: #1.C环境配置 gcc、gdb、g #2.gpu环境 cuda、cudnn #3.Cmake环境 CMake #4.OpenCV环境 OpenCV #5.Ten…...
6Python的Pandas:数据读取与输出
Pandas是一个强大的Python数据分析库,提供了读取和输出数据的多种功能。以下是一些常见的数据读取与输出方法: 1. 读取CSV 读取数据 从CSV文件读取数据 import pandas as pd# 读取CSV文件 df pd.read_csv(file_path.csv) print(df.head())从Excel文…...
ubuntu 网络 通讯学习笔记2
1.ubuntu 网络常用命令 在Ubuntu中,有许多网络相关的常用命令。以下是一些主要命令及其用途: ifconfig:此命令用于显示和配置网络接口信息。你可以使用它来查看IP地址、子网掩码、广播地址等。 例如:ifconfig 注意:…...
深入理解JS中的事件委托
JavaScript中的事件委托是一种非常有用的事件处理模式,它允许我们利用事件模型的事件冒泡阶段来减少事件处理器的数量,提高网页性能。本文将介绍事件委托的概念、工作原理、优点以及如何在实际项目中应用事件委托。 1、事件模型 事件模型指在Web开发中,处理和管理事件(如…...
ES6从入门到精通:前言
ES6简介 ES6(ECMAScript 2015)是JavaScript语言的重大更新,引入了许多新特性,包括语法糖、新数据类型、模块化支持等,显著提升了开发效率和代码可维护性。 核心知识点概览 变量声明 let 和 const 取代 var…...
Admin.Net中的消息通信SignalR解释
定义集线器接口 IOnlineUserHub public interface IOnlineUserHub {/// 在线用户列表Task OnlineUserList(OnlineUserList context);/// 强制下线Task ForceOffline(object context);/// 发布站内消息Task PublicNotice(SysNotice context);/// 接收消息Task ReceiveMessage(…...
23-Oracle 23 ai 区块链表(Blockchain Table)
小伙伴有没有在金融强合规的领域中遇见,必须要保持数据不可变,管理员都无法修改和留痕的要求。比如医疗的电子病历中,影像检查检验结果不可篡改行的,药品追溯过程中数据只可插入无法删除的特性需求;登录日志、修改日志…...
Python爬虫实战:研究feedparser库相关技术
1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的信息资源。RSS(Really Simple Syndication)作为一种标准化的信息聚合技术,被广泛用于网站内容的发布和订阅。通过 RSS,用户可以方便地获取网站更新的内容,而无需频繁访问各个网站。 然而,互联网…...
LeetCode - 394. 字符串解码
题目 394. 字符串解码 - 力扣(LeetCode) 思路 使用两个栈:一个存储重复次数,一个存储字符串 遍历输入字符串: 数字处理:遇到数字时,累积计算重复次数左括号处理:保存当前状态&a…...
【Zephyr 系列 10】实战项目:打造一个蓝牙传感器终端 + 网关系统(完整架构与全栈实现)
🧠关键词:Zephyr、BLE、终端、网关、广播、连接、传感器、数据采集、低功耗、系统集成 📌目标读者:希望基于 Zephyr 构建 BLE 系统架构、实现终端与网关协作、具备产品交付能力的开发者 📊篇幅字数:约 5200 字 ✨ 项目总览 在物联网实际项目中,**“终端 + 网关”**是…...
Android15默认授权浮窗权限
我们经常有那种需求,客户需要定制的apk集成在ROM中,并且默认授予其【显示在其他应用的上层】权限,也就是我们常说的浮窗权限,那么我们就可以通过以下方法在wms、ams等系统服务的systemReady()方法中调用即可实现预置应用默认授权浮…...
用docker来安装部署freeswitch记录
今天刚才测试一个callcenter的项目,所以尝试安装freeswitch 1、使用轩辕镜像 - 中国开发者首选的专业 Docker 镜像加速服务平台 编辑下面/etc/docker/daemon.json文件为 {"registry-mirrors": ["https://docker.xuanyuan.me"] }同时可以进入轩…...
【JavaWeb】Docker项目部署
引言 之前学习了Linux操作系统的常见命令,在Linux上安装软件,以及如何在Linux上部署一个单体项目,大多数同学都会有相同的感受,那就是麻烦。 核心体现在三点: 命令太多了,记不住 软件安装包名字复杂&…...
蓝桥杯3498 01串的熵
问题描述 对于一个长度为 23333333的 01 串, 如果其信息熵为 11625907.5798, 且 0 出现次数比 1 少, 那么这个 01 串中 0 出现了多少次? #include<iostream> #include<cmath> using namespace std;int n 23333333;int main() {//枚举 0 出现的次数//因…...
