JDK8新特性
Lembda表达式
lembda表达式是一个简洁、可传递的匿名函数,实现了把代码块赋值给一个变量的功能
是我认为jdk1.8中最让人眼前一亮的特性(我没用过其他函数式的语言)
在了解表达式之前,我们先看两个概念
函数式接口
含有且仅含有一个抽象方法,Lembda表达式需要借助函数式接口实现。
通常来说我们在这个接口定义上加上@FunctionInterface注解,语义化地标注它是一个函数式接口,起到的作用和@Override相同,只起到检查作用。
允许对接口进行默认实现
这次更新中新增了一个default关键字,用来在接口中添加非抽象的方法实现。这个特性也被成为扩展方法。
在实际使用Lembda表达式的时候,我们通过表达式实现相应的接口得到接口的实现对象。我们可以直接通过这些对象调用接口中的默认实现。
Lembda表达式格式
Lembda表达式通过左侧的参数,右侧的表达式和中间的右箭头组成:
(parameter1,parameter12,...) -> {
expression;
...
return xxx;
}
可以理解为方法的另一种表现形式;
比如说这个接收a和b两个int参数,返回两数之和的方法
int addNum(int a,int b){
return a + b;
}
可以写成下面这个形式
(int a,int b) -> {
return a + b
}
需要注意的是:
参数可以为空 ()->xxx 这代表了无参方法
参数为一个值得时候,可以省略参数的括号 x->xxx
参数类型可以省略,Jdk会自动在接口中匹配相应的类型
表达式只有一行的时候不需要;,有多行的时候需要加上;
表达式可以是一个数字(直接返回这个数字),一个算式;可以是普通的一个语句(无返回,相当于void)
当表达式只有一行且最终为返回值时,return可以省略
参数的名不能和局部变量相同
表达式中直接调用的变量(不是传入的),必须是显示声明为final或事实上的final类型
自定义函数式接口并调用
我们定义一个入参是两个int类型,返回值也是int类型的方法;
然后添加一个将一个数加1并返回的扩展方法,使用default关键字;
@FunctionalInterface
interface Append {
int append(int a, int b);
default int addOne(int num) {
return ++num;
}
}
现在,我们使用Lambda表达式对这个接口进行实现:
Append append = (int a, int b) -> {
return a + b;
};
然后我们调用这个方法,也调用接口的扩展方法
int num = append.append(1, 2);
int numAddOne = append.addOne(num);
System.out.println(num);//3
System.out.println(numAddOne);//4
根据上面总结的表达式格式注意事项,我们可以对表达式进行简化
当代码只有一行地时候可以不加分号
Append append = (int a, int b) -> { return a + b };
去掉参数类型,并且进一步简化右侧
Append append = (a, b) -> a + b;
方法调用
如果你使用的是IDEA较新版本,它会提示将它简化成另一种形式;
Append append = Integer::sum;
这是方法引用,在表达式中,我们可以通过类::方法的格式,直接将这个方法作为表达式的内容;
因此使用这种形式的时候无需指定参数,返回值等,因为这些已经确定了;
如果方法重载,jdk会根据传入的方法找到合适的方法
我们进入这个方法,发现它和我们的表达式相同
public static int sum(int a, int b) {
return a + b;
}
我们还可以通过这种形式获得构造方法的调用
类::new
返回值就是通过合适构造方法(同样根据入参选择)创建的这个类的对象
Lambda表达式中变量的访问范围
外部final变量
成员变量
静态变量
需要注意,在表达式中无法访问接口的扩展方法
JDK自带的常用函数式接口
Predicate 判断,
boolean test(T t); 对单一参数进行判断,拓展方法可以对Predicate进行or,and的逻辑拼接,进行更复杂的逻辑判断
利用我们在外部设定的条件对于传入的参数进行校验并返回验证通过与否
Consumer 消费者
void accept(T t); 消费掉参数,啥也不返回,拓展方法可以拼接消费者链,按次序依次执行
接收参数并依据传递的行为应用传递的参数值
Function<T, R> 方法
R apoly(T t); ,该接口中有很多拓展方法,可以将多个Function拼接在一起,进行复杂的逻辑运算
执行转换操作,输入类型 T 的数据,返回 R 类型的结果
这三个是最重要的接口,Stream也用到这些接口,下面我强行使用这三个接口
/*Predicate<T> 判断*/
Predicate<String> stringPredicate = str -> StringUtils.isBlank(str) || "error".equalsIgnoreCase(str);
/*Consumer<T>*/
Consumer<String> stringConsumer = str -> {
if (StringUtils.isBlank(str) || "error".equalsIgnoreCase(str)) {
System.out.println("Consumer失败");
}
};
/*Function<T,R>*/
Function<String, String> stringStringFunction = str -> {
if (StringUtils.isBlank(str) || "error".equalsIgnoreCase(str)) {
return "Function失败";
} else {
return "Function成功";
}
};
String in = "error";
if (stringPredicate.test(in)) {
System.out.println("Predicate失败");
}
stringConsumer.accept(in);
System.out.println(stringStringFunction.apply(in));
二.Stream流
Stream使用上面说的JDK自带的函数式接口
Stream是一种函数式编程对集合,数组,I/O channel, 产生器generator等数据的操作方式,它有以下特点:
无储存,Stream本身不会储存数据
不会修改传入的数据源
惰性执行:Stream上的操作不会立即执行,而是会在真正需要的时候进行
可消费性:Stream只能被消费一次,类似迭代器,想要再次遍历,必须生成新的Stream.
在学习过程中,我发现Stream某些操作之后返回的仍然是流,而有些操作返回的确实真实的被处理之后数据,Stream的操作可以据此分为两种
中间操作 总是会惰式执行,调用中间操作只会生成一个标记了该操作的新stream。
结束操作 会触发实际计算,计算发生时会把所有中间操作积攒的操作以pipeline的方式执行,这样可以减少迭代次数。计算完成之后stream就会失效。
总之,把Stream看做一根水管就好啦,一开始把一根根水管拼接起来(中间操作),安装一个水龙头(结束操作),确认有水龙头之后水就依次通过水管,最后通过水龙头进入下水道(不能重复使用);
Collection.stream() 或者 Collection.parallelStream() 来创建一个串行Stream或者并行Stream。
常用的Stream方法
中间操作
sorted排序
Stream<T> sorted();
Stream<T> sorted(Comparator<? super T> comparator);
这是一个有状态的操作
用法 作用
sorted() 自然排序
sorted(Comparator.reverseOrder()) 自然逆向排序
sorted(Comparator.comparing(Student::getAge)) 通过某些元素排序
sorted(Comparator.comparing(Student::getAge).reversed()) 通过某些元素逆向排序
Comparator是比较器
map元素操作
<R> Stream<R> map(Function<? super T, ? extends R> mapper);
用于对每个元素进行操作,并且将处理后的Stream返回
例如map(i->i*2)将所有数据进行平方操作
filter过滤
Stream<T> filter(Predicate<? super T> predicate);
入参为Predicate,lembda表达式返回值是boolean;
如果表达式为flase,则剔除数据,只留符合条件的
过滤是中间操作:Stream<Integer> integerStream = intList.stream().filter(i -> i > 4);
limit限制
Stream<T> limit(long maxSize);
限制数据的数量,这是一个有状态的短路的操作。
distinct去重
Stream<T> distinct();
去除重复的操作,这是一个有状态的操作
结束操作
forEach迭代
void forEach(Consumer<? super T> action);
入参是Consumer,表达式不需要返回值,方法本身返回值void,所以是结束操作
常用的方法是forEach(System.out::println);
collect存入容器
<R, A> R collect(Collector<? super T, A, R> collector);
将数据存入一个Collection或Map
toArray存入数组
Object[] toArray();
将结果存入一个数组中
count计数
long count();
计算流中元素的数量
max 和 min
Optional<T> min(Comparator<? super T> comparator);
Optional<T> max(Comparator<? super T> comparator);
根据一个比较器找到最大或最小元素
anyMatch allMatch noneMatch 匹配
boolean anyMatch(Predicate<? super T> predicate);三个都一样
是否至少有一个元素匹配
是否每一个元素都匹配
是否没有元素匹配
findFirst findAny 查找
Optional<T> findFirst();
查找第一个元素
查找随机的一个元素
Stream常用代码
List转Map
Map<Integer, A> aMap = aList.stream().col
相关文章:

JDK8新特性
Lembda表达式 lembda表达式是一个简洁、可传递的匿名函数,实现了把代码块赋值给一个变量的功能 是我认为jdk1.8中最让人眼前一亮的特性(我没用过其他函数式的语言) 在了解表达式之前,我们先看两个概念 函数式接口 含有且仅含有一个抽象方法&…...

X86_64函数调用汇编程序分(2)
X86_64函数调用汇编程序分(2) 1 X86_64寄存器使用标准2 leaveq和retq指令2.1 leaveq2.2 retq 3 执行leaveq和retq之后栈的结构3.1 执行leaveq之后栈的结构3.1.1 test_fun_b函数执行leaveq之前的栈结构示意图3.1.2 test_fun_b函数执行leaveq之后的栈结构示…...
组件传值之ref(解决父传子动态绑定问题)
在父组件往子组件传值,子组件中要显示父组件的信息,首先是在网上搜的watch 来监听组组件的props,但是父组件只传一次,后续再更改就没了,所以我用的$refs props:{params:{type:Object;defult():{return {} } } }watch:{params: {/…...

vscode-server
1know_host清除 2 删除服务器里的home/user/.vscode-server(不是根root下的vscode-server),删除时用户名保持一致。 3 ssh配置文件 /etc/ssh/sshd_config[想改变,使用root,修改文件权限] 4 删除修改后,重启Windows下…...
ubuntu 20.04安装开发环境总结_安装python
Ubuntu 20.04 是一款主要面向开发人员的操作系统之一,与此同时,它还支持多种开发环境和工具的使用。但是因为对市面上各种软件的支持没有window那样友好,所以对ubuntu系统安装配置各种环境的问题做了个总结 安装 PyCharm: 可以从…...
尚硅谷_宋红康_IntelliJ IDEA 常用快捷键一览表
1-IDEA的日常快捷键 第1组:通用型 说明快捷键复制代码-copyctrl c粘贴-pastectrl v剪切-cutctrl x撤销-undoctrl z反撤销-redoctrl shift z保存-save allctrl s全选-select allctrl a 第2组:提高编写速度(上) 说明快捷…...
Java设计模式之建造者模式详解(Builder Pattern)
在日常的开发工作中,我们常常需要创建一些复杂的对象。这些对象可能包含许多不同的属性,并且这些属性的初始化过程可能相当复杂。在这种情况下,建造者模式是一种非常有用的设计模式,因为它允许我们分步骤地创建复杂的对象。 概念和…...

TCP的滑动窗口与拥塞控制
客户端每发送的一个包,服务器端都应该有个回复,如果服务器端超过一定的时间没有回复,客户端就会重新发送这个包,直到有回复。 为了保证顺序性,每一个包都有一个 ID。在建立连接的时候,会商定起始的 ID 是什…...
MySQL更新语句执行过程
执行流程 update t set name XXX where id 1; 加载id1的记录所在的整页数据到缓存池;旧值写入undolog便于回滚;更新内存数据;写redo log到RedoBuff;redo log顺序写入磁盘,准备提交事务(prepare阶段&…...

Matlab图像处理-彩色图像基础
彩色的物理认识 人类能够感知的物体的颜色是由物体反射的光的性质决定的。如图8-2所示,可见光是由电磁波谱中较窄的波段组成。 如果物体反射的光在所有可见光波长范围内都是平衡的,那么从观察者的角度来看,它是白色的; 如果物体…...
MATLAB算法实战应用案例精讲-【数模应用】数据中台
目录 前言 几个高频面试题目 数据中台、数仓、大数据平台的区别 1)数据中台VS数据仓库...
el-form动态检验无法生效问题(已解决)
要对el-form里面的字段动态生成校验规则,测试了一系列的骚操作也无法生效,要么是require视图生效了,校验规则还是不生效;看了csdn里面好多方案,都是废话,废话,直接上硬货,最终总结如下ÿ…...

【python】代码学习过程问题总结
目录 1. 使用 conda 创建并进入虚拟环境 2. pycharm 选择 interpreter 的时候,在虚拟环境中找不到 python.exe 3.(py & python)ModuleNotFoundError: No module named XXX 4. AttributeError: module ‘tensorflow‘ has no attribu…...

Qt应用开发(基础篇)——菜单 QMenu
一、前言 QMenu类继承于QWidget,它提供了一个菜单样式的小部件,用于菜单栏、上下文菜单和一些弹出式菜单。 QMenu菜单的选项是可选的,它可以是一个下拉的菜单,也可以是独立的上下文菜单。下拉菜单通常作用于当用户单击相应的项目或…...

MySQL-DDL语句
MySQL-DDL语句 数据库操作语句增删数据库查看数据库列表创建数据库进入(使用)数据库/查看当前所在的数据库查看数据库的建库语句查看数据库的编码集和校验集删除数据库修改数据库的编码集查看数据库支持的编码集和校验集 数据库备份备份单个数据库恢复数…...

总结987
考研倒计时102天 时间记录: 6:20起床 7:00~7:40早读,13年tex2 7:50~8:20实验室 8:30~8:34列日计划 8:40~11:18进步本回顾,记录 11:20~12:20计算机网络网课 2:10~3:05计网20道选择题 3:07~4:42政治1000题25道选择题纠错 …...

【服务器 | 测试】如何在centos 7上面安装jmeter
安装之前需要几个环境,以下是列出的几个环境 CentOS 7.7 64位JDK 1.8JMeter 5.2 1. 下载jmeter安装包 JMeter是开源的工具,安装 JMeter 要先安装好 JDK 的环境,安装JDK在前面的文章已经讲到 JMeter最新版下载地址:Apache JMeter…...

20.04部署cartographer
部署cartographer sudo apt-get update sudo apt-get install -y python3-wstool python3-rosdep ninja-build stow下载cartographer新建了一个ws mkdir carto_ws cd carto_ws wstool init src wstool merge -t src https://raw.githubusercontent.com/cartographer-project/…...

djangoMTV初探
1.restful请求方式 一个视图对应多个操作(增删改查) 老的方式 views.py from django.shortcuts import render from django.http import HttpResponse,request,QueryDict, JsonResponse from myapp.models import User from django.views.generi…...

Minecraft--基于云服务器搭建自己的服务器--简易搭建
阿丹: 上一个项目结束了。但是看着自己的服务器想着能不能做点啥子吧。想到了之前和兄弟们玩的麦块。好久没和兄弟们一起玩耍了。怀念之前一起连一个wifi玩我的世界的时候是真快乐。于是尝试自己动手搭建一个我的世界服务器,邀请兄弟们重温一下快乐。 提…...

Docker 离线安装指南
参考文章 1、确认操作系统类型及内核版本 Docker依赖于Linux内核的一些特性,不同版本的Docker对内核版本有不同要求。例如,Docker 17.06及之后的版本通常需要Linux内核3.10及以上版本,Docker17.09及更高版本对应Linux内核4.9.x及更高版本。…...

XCTF-web-easyupload
试了试php,php7,pht,phtml等,都没有用 尝试.user.ini 抓包修改将.user.ini修改为jpg图片 在上传一个123.jpg 用蚁剑连接,得到flag...

springboot 百货中心供应链管理系统小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,百货中心供应链管理系统被用户普遍使用,为方…...
利用ngx_stream_return_module构建简易 TCP/UDP 响应网关
一、模块概述 ngx_stream_return_module 提供了一个极简的指令: return <value>;在收到客户端连接后,立即将 <value> 写回并关闭连接。<value> 支持内嵌文本和内置变量(如 $time_iso8601、$remote_addr 等)&a…...

iPhone密码忘记了办?iPhoneUnlocker,iPhone解锁工具Aiseesoft iPhone Unlocker 高级注册版分享
平时用 iPhone 的时候,难免会碰到解锁的麻烦事。比如密码忘了、人脸识别 / 指纹识别突然不灵,或者买了二手 iPhone 却被原来的 iCloud 账号锁住,这时候就需要靠谱的解锁工具来帮忙了。Aiseesoft iPhone Unlocker 就是专门解决这些问题的软件&…...
将对透视变换后的图像使用Otsu进行阈值化,来分离黑色和白色像素。这句话中的Otsu是什么意思?
Otsu 是一种自动阈值化方法,用于将图像分割为前景和背景。它通过最小化图像的类内方差或等价地最大化类间方差来选择最佳阈值。这种方法特别适用于图像的二值化处理,能够自动确定一个阈值,将图像中的像素分为黑色和白色两类。 Otsu 方法的原…...
什么是EULA和DPA
文章目录 EULA(End User License Agreement)DPA(Data Protection Agreement)一、定义与背景二、核心内容三、法律效力与责任四、实际应用与意义 EULA(End User License Agreement) 定义: EULA即…...
unix/linux,sudo,其发展历程详细时间线、由来、历史背景
sudo 的诞生和演化,本身就是一部 Unix/Linux 系统管理哲学变迁的微缩史。来,让我们拨开时间的迷雾,一同探寻 sudo 那波澜壮阔(也颇为实用主义)的发展历程。 历史背景:su的时代与困境 ( 20 世纪 70 年代 - 80 年代初) 在 sudo 出现之前,Unix 系统管理员和需要特权操作的…...

涂鸦T5AI手搓语音、emoji、otto机器人从入门到实战
“🤖手搓TuyaAI语音指令 😍秒变表情包大师,让萌系Otto机器人🔥玩出智能新花样!开整!” 🤖 Otto机器人 → 直接点明主体 手搓TuyaAI语音 → 强调 自主编程/自定义 语音控制(TuyaAI…...
浅谈不同二分算法的查找情况
二分算法原理比较简单,但是实际的算法模板却有很多,这一切都源于二分查找问题中的复杂情况和二分算法的边界处理,以下是博主对一些二分算法查找的情况分析。 需要说明的是,以下二分算法都是基于有序序列为升序有序的情况…...