Java8新特性1——函数式接口lambda表达式
Java8新特性1——函数式接口&lambda表达式
注:以下内容基于Java 8,所有代码都已在Java 8环境下测试通过
目录:
- Java8新特性1——函数式接口&lambda表达式
- 方法引用
- Stream
1. 函数式接口
如果在一个接口中,有且只有一个抽象方法,则该接口被称为函数式接口。如:
interface Test {void test();
}
注:
可以在接口前使用 @FunctionalInterface 注解,判断这个接口是否是⼀个函数式接口。如:
@FunctionalInterface
interface Test1 {//有且仅有一个抽象方法,是函数式接口void test();
}@FunctionalInterface
interface Test2 {//有且仅有一个抽象方法,是函数式接口void test();default void f() {}
}@FunctionalInterface
interface Test3 {//没有抽象方法,不是函数式接口,编译器报错
}@FunctionalInterface
interface Test4 {//有多个抽象方法,不是函数式接口,编译器报错void test1();void test2();
}
2. lambda表达式
2.1 lambda表达式作用
lambda表达式是一个匿名函数,用于简化函数式接口的实现。
在Java中,接口不能实例化,但接口对象可以指向实现类对象。当没有实现类对象时,可以通过匿名类的方式,如:
public class Main {public static void main(String[] args) {Test test = new Test() {@Overridepublic void f() {System.out.println("使用匿名函数的方式实现了函数式接口");}};test.f();}
}@FunctionalInterface
interface Test {void f();
}
使用匿名类的方式代码不是很简洁,因此引入了lambda表达式,如:
public class Main {public static void main(String[] args) {Test test = () -> System.out.println("使用lambda表达式的方式实现了函数式接口");test.f();}
}@FunctionalInterface
interface Test {void f();
}
在使用lambda表达式之后,代码变得简洁了很多,因此可以说lambda表达式是和函数式接口相辅相成的。在上面的代码中,lambda表达式实际做了以下三个工作:
-
自动实现接口
Test test = new Test(); -
将
->前的参数自动添加到抽象函数里面(上面代码中抽象函数没有参数)void f(); -
将
->后的语句作为抽象函数的方法体void f(){System.out.println("使用lambda表达式的方式实现了函数式接口"); }
2.2 lambda表达式语法格式
lambda表达式的格式如下:
(参数1, 参数2, ……) -> {方法体;
}
其中:
- 参数要求和函数式接口中抽象方法的参数一致(包括数量和类型以及顺序)
- 如果函数式接口中抽象方法有返回值,则实现的时候也需要返回值
public class Main {public static void main(String[] args) {Test test = (int x, int y) -> {//参数、返回值与函数式接口中抽象方法一致return x + y;};test.add(1, 2);}
}@FunctionalInterface
interface Test {int add(int x, int y);
}
2.3 lambda表达式的精简
-
参数精简
- 参数类型可以省略,若省略一个类型参数,则所有的类型参数都要省略
- 若只有一个参数,则小括号可以省略
- 若参数为0或者多于1个,则小括号不可以省略
-
方法体精简
- 若方法体中只有一行代码,则花括号可以省略
- 若方法体中只有一行代码且是return语句,则在省略大括号的时候还需要去掉return关键字
- 若方法体中有多行代码或者使用了return语句,则大括号不可以省略
public class Main {public static void main(String[] args) {//只有一个参数,省略了小括号//只有一条return语句,省略了花括号即return关键字Test test = x -> Math.exp(x);test.exp(1);} }@FunctionalInterface interface Test {double exp(double x); }2.4 变量作用域
- lambda表达式只可以访问外部变量,但不能修改外部变量
- lambda表达式访问的外部变量一般都是声明为 final 的,但也可以不用声明为 final ,但该变量在声明后不能被修改
- lambda表达式中不允许声明一个与局部变量同名的参数或局部变量
public class Main {static final int a = 0;public static void main(String[] args) {final int num1 = 10;int num2 = 20;//num2 = 40; //声明后不能被修改Test test1 = x -> {System.out.println(num1);//可以访问外部被声明为 final 的变量System.out.println(num2);//可以访问外部的普通变量//num1 = 20;//只能访问,不能修改//num2 = 20;//只能访问,不能修改//int num1 = 20;//不允许声明一个与局部变量同名的局部变量return Math.exp(x);};//num2 = 40; //声明后不能被修改test1.exp(1);//不允许声明一个与局部变量同名的参数//Test test2 = num1 -> Math.exp(num1);} }@FunctionalInterface interface Test {double exp(double x); }
3. 四大函数式接口
为了让开发者高效地使用函数式接口,Java 8 在 java.util.function 包下提供了许多函数式接口,以下四种是最为常见的:
| 接口原型 | 抽象方法 | 备注 |
|---|---|---|
| Consumer< T > | accept(T t) | 消费型接口 |
| Supplier< T > | T get() | 供给型接口 |
| Function<T, R> | R apply(T t) | 函数型接口 |
| Predicate< T > | boolean test(T t) | 断言型接口 |
3.1 Consumer< T >:消费型接口
该接口只接收输入参数但不输出返回值,消费对象,只进不出。
-
接口原型:
@FunctionalInterface public interface Consumer<T> {void accept(T t); } -
使用示例:
import java.util.function.Consumer;public class Main {public static void main(String[] args) {Consumer<Integer> acc = (t) -> System.out.println(t);//实现 Consumer 接口acc.accept(10);} }
3.2 Supplier< T >:供给型接口
该接口只输出返回值但不接收输入参数,生成对象,只出不进。
-
接口原型:
public interface Supplier<T> {T get(); } -
使用示例:
import java.util.function.Supplier;public class Main {public static void main(String[] args) {Supplier<Integer> sup = () -> 10;//实现 Supplier 接口System.out.println(sup.get());} }
3.3 Function<T, R>:函数型接口
该接口既接收输入参数又输出返回值,用于指定特定功能,有进有出。
-
接口原型:
@FunctionalInterface public interface Function<T, R> {R apply(T t); } -
使用示例:
import java.util.function.Function;public class Main {public static void main(String[] args) {Function<Integer, String> fun = (x) -> {//实现 Function 接口String out = "输入的整数是" + x;return out;};System.out.println(fun.apply(10));} }
3.4 Predicate< T >:断言型接口
该接口既接收输入参数又输出返回值,且返回值只能是布尔值,用于条件判断,有进有出。
-
函数原型:
public interface Predicate<T> {boolean test(T t); } -
使用示例:
import java.util.function.Predicate;public class Main {public static void main(String[] args) {Predicate<Integer> pre = (x) -> x % 2 == 0;//实现 Predicate 接口int a = 10;if (pre.test(10)) {System.out.println(a + "是偶数");} else {System.out.println(a + "是奇数");}} }
相关文章:
Java8新特性1——函数式接口lambda表达式
Java8新特性1——函数式接口&lambda表达式 注:以下内容基于Java 8,所有代码都已在Java 8环境下测试通过 目录: Java8新特性1——函数式接口&lambda表达式方法引用Stream 1. 函数式接口 如果在一个接口中,有且只有一个抽…...
文本标注技术方案(NLP标注工具)
Doccano doccano 是一个面向人类的开源文本注释工具。它为文本分类、序列标记和序列到序列任务提供注释功能。您可以创建用于情感分析、命名实体识别、文本摘要等的标记数据。只需创建一个项目,上传数据,然后开始注释。您可以在数小时内构建数据集。 支持…...
03-使用一个不可变对象作为key,红黑树怎么比较大小?
使用一个不可变对象作为key,红黑树怎么比较大小? 答:Java 中的红黑树是通过左旋、右旋的方式来维护树的平衡性,而左旋、右旋又依赖于节点大小的比较。对于使用不可变对象作为key实际上是可以的,因为比较key的大小本身…...
2021江苏省赛热身赛 C Magic Rabbit(数形结合)
2021江苏省赛热身赛 C Magic Rabbit(数形结合) Magic Rabbit 非常好且巧妙地一道题。 大意:给出三种溶液 , 三种溶液分别含有不同浓度的 x ,y 两种物质。 溶液x (mg/ml)y (mg/ml)溶液1x1y1溶液2x2y2溶液3x3y3 给出 Q 组询问 ,…...
AES加密(2):AES代码实现解析
在我的上一篇文章AES基础知识和计算过程中,大概介绍了AES(Rijndael)加密的整个过程。那么在这一篇文章中,就来看一下AES在代码中是如何实现的,也有助于我们理解其中的一些细节。 本篇文章所用的AES代码来源于Szymon Stefanek的开源C代码 文章…...
SpringBoot项目通过分词器生成词云
目录 前言一、词云是什么?二、使用步骤1.引入依赖2.application.yml3.Controller4.分词工具类4.词云生成工具类、支持输出文件和字节流 注意 前言 公司项目涉及到员工任务管理,需要从员工任务中获取任务信息生成个人词云图,可以把员工任务中…...
Nacos 配置管理及相关使用
文章目录 Nacos 配置管理一、统一配置管理1、在Nacos 中添加配置文件2、从微服务拉取配置3、配置实现步骤(1)引入 nacos-config 依赖(2)添加 bootstrap.yml(4)在 nacos 中添加配置 二、配置热更新1、配置热…...
重发布与路由策略
华子目录 重发布重发布条件重发布配置规则重发布名词配置命令ospf往rip重发布(重发布动态)静态往rip重发布(重发布静态)直连往rip重发布(重发布直连)rip往ospf重发布(重发布动态)静态…...
57. 插入区间(C++题解)
57. 插入区间 插入区间 给你一个无重叠的 ,按照区间起始端点排序的区间列表。 在列表中插入一个新的区间,你需要确保列表中的区间仍然有序且不重叠(如果有必要的话,可以合并区间)。 示例 1: 输入&#x…...
【数据结构Java版】 初识泛型和包装类
目录 1.包装类 1.1基本数据类型以及它们所对应的包装类 1.2装箱和拆箱 1.3自动装箱和自动拆箱 2.什么是泛型 3.引出泛型 4.泛型类的使用 4.1语法 4.2示例 4.3类型推导 5.泛型是如何编译的 5.1擦除机制 5.2正确的写法 6.泛型的上届 6.1语法 6.2示例 …...
Spring中如何解决循环依赖问题的三种方法
什么是循环依赖问题 在 Spring 中,循环依赖问题指的是两个或多个 bean 之间相互依赖形成的闭环。具体而言,当 bean A 依赖于 bean B,同时 bean B 也依赖于 bean A,就形成了循环依赖。 循环依赖问题在 Spring 容器中是一个非常常…...
【ArcGIS Pro二次开发】(65):进出平衡SHP转TXT、TXT转SHP
最近一个小伙伴提了这么一个需求,需要把TXT和SHP进行互转。 这种TXT文件其实遇到了好几个版本,都有一点小差异。之前已经做过一个TXT转SHP的工具,但好像不适用。于是针对这个版本,做了互转的2个工具。 【SHP转TXT】 一、要实现的…...
Shell开发实践:服务器的磁盘、CPU、内存的占用监控
🏆作者简介,黑夜开发者,CSDN领军人物,全栈领域优质创作者✌,CSDN博客专家,阿里云社区专家博主,2023年6月CSDN上海赛道top4。 🏆数年电商行业从业经验,历任核心研发工程师…...
超详细 async和await 项目实战运用(附加文字解答+源码)
文章目录 问题描述async什么是 asyncasync 的作用async 的应用场景async 优点 await什么是 awaitawait 的作用await 的应用场景await 的优点async和 await结合使用 结束语 大家好!又到了愉快的周末假期,今天是2023年9月3日|农历七月十九,我最…...
Maven入门教程(三):Maven语法
视频教程:Maven保姆级教程 Maven入门教程(一):安装Maven环境 Maven入门教程(二):idea/Eclipse使用Maven Maven入门教程(三):Maven语法 Maven入门教程(四):Nexus私服 Maven入门教程(五):自定义脚手架 6.Mav…...
C++技术点,故事解析
语言的魅力 从人类诞生开始 ,南方古猿到现代人类经历了非常多变化; 南方古猿到能人 有什么变化? 能人会使用工具,由于会使用工具 就可以获得肉类食物,当然只能吃一些动物腐肉 直到进化成直立人的晚期,在东…...
数据结构(Java实现)-字符串常量池与通配符
字符串常量池 在Java程序中,类似于:1, 2, 3,3.14,“hello”等字面类型的常量经常频繁使用,为了使程序的运行速度更快、更节省内存,Java为8种基本数据类型和String类都提供了常量池。…...
python强化学习--gym安装与使用
最近开始学习强化学习,第一步肯定是要学会安装和使用pym,原本以为很简单,事实上确实很简单,但是遇到一个小问题,就是安装gym之后,在应用的过程中,游戏界面没有显示出来,了解后才知道…...
105. 从前序与中序遍历序列构造二叉树
给定两个整数数组 preorder 和 inorder ,其中 preorder 是二叉树的先序遍历, inorder 是同一棵树的中序遍历,请构造二叉树并返回其根节点。 思路:题目给出了先序遍历和中序遍历的结果,因为先序遍历遵循根–>左–>…...
(第六天)初识Spring框架-SSM框架的学习与应用(Spring + Spring MVC + MyBatis)-Java EE企业级应用开发学习记录
SSM框架的学习与应用(Spring Spring MVC MyBatis)-Java EE企业级应用开发学习记录(第六天)初识Spring框架 昨天我们已经把Mybatis框架的基本知识全部学完,内容有Mybatis是一个半自动化的持久层ORM框架,深入学习编写动态SQL&a…...
挑战杯推荐项目
“人工智能”创意赛 - 智能艺术创作助手:借助大模型技术,开发能根据用户输入的主题、风格等要求,生成绘画、音乐、文学作品等多种形式艺术创作灵感或初稿的应用,帮助艺术家和创意爱好者激发创意、提高创作效率。 - 个性化梦境…...
【网络】每天掌握一个Linux命令 - iftop
在Linux系统中,iftop是网络管理的得力助手,能实时监控网络流量、连接情况等,帮助排查网络异常。接下来从多方面详细介绍它。 目录 【网络】每天掌握一个Linux命令 - iftop工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景…...
Linux 文件类型,目录与路径,文件与目录管理
文件类型 后面的字符表示文件类型标志 普通文件:-(纯文本文件,二进制文件,数据格式文件) 如文本文件、图片、程序文件等。 目录文件:d(directory) 用来存放其他文件或子目录。 设备…...
2025 后端自学UNIAPP【项目实战:旅游项目】6、我的收藏页面
代码框架视图 1、先添加一个获取收藏景点的列表请求 【在文件my_api.js文件中添加】 // 引入公共的请求封装 import http from ./my_http.js// 登录接口(适配服务端返回 Token) export const login async (code, avatar) > {const res await http…...
相机从app启动流程
一、流程框架图 二、具体流程分析 1、得到cameralist和对应的静态信息 目录如下: 重点代码分析: 启动相机前,先要通过getCameraIdList获取camera的个数以及id,然后可以通过getCameraCharacteristics获取对应id camera的capabilities(静态信息)进行一些openCamera前的…...
Robots.txt 文件
什么是robots.txt? robots.txt 是一个位于网站根目录下的文本文件(如:https://example.com/robots.txt),它用于指导网络爬虫(如搜索引擎的蜘蛛程序)如何抓取该网站的内容。这个文件遵循 Robots…...
C++.OpenGL (10/64)基础光照(Basic Lighting)
基础光照(Basic Lighting) 冯氏光照模型(Phong Lighting Model) #mermaid-svg-GLdskXwWINxNGHso {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-GLdskXwWINxNGHso .error-icon{fill:#552222;}#mermaid-svg-GLd…...
AI,如何重构理解、匹配与决策?
AI 时代,我们如何理解消费? 作者|王彬 封面|Unplash 人们通过信息理解世界。 曾几何时,PC 与移动互联网重塑了人们的购物路径:信息变得唾手可得,商品决策变得高度依赖内容。 但 AI 时代的来…...
Pinocchio 库详解及其在足式机器人上的应用
Pinocchio 库详解及其在足式机器人上的应用 Pinocchio (Pinocchio is not only a nose) 是一个开源的 C 库,专门用于快速计算机器人模型的正向运动学、逆向运动学、雅可比矩阵、动力学和动力学导数。它主要关注效率和准确性,并提供了一个通用的框架&…...
#Uniapp篇:chrome调试unapp适配
chrome调试设备----使用Android模拟机开发调试移动端页面 Chrome://inspect/#devices MuMu模拟器Edge浏览器:Android原生APP嵌入的H5页面元素定位 chrome://inspect/#devices uniapp单位适配 根路径下 postcss.config.js 需要装这些插件 “postcss”: “^8.5.…...
