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

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表达式实际做了以下三个工作:

  1. 自动实现接口

    Test test = new Test();
    
  2. -> 前的参数自动添加到抽象函数里面(上面代码中抽象函数没有参数)

    void f();
    
  3. -> 后的语句作为抽象函数的方法体

    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 变量作用域

    1. lambda表达式只可以访问外部变量,但不能修改外部变量
    2. lambda表达式访问的外部变量一般都是声明为 final 的,但也可以不用声明为 final ,但该变量在声明后不能被修改
    3. 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表达式 注&#xff1a;以下内容基于Java 8&#xff0c;所有代码都已在Java 8环境下测试通过 目录&#xff1a; Java8新特性1——函数式接口&lambda表达式方法引用Stream 1. 函数式接口 如果在一个接口中&#xff0c;有且只有一个抽…...

文本标注技术方案(NLP标注工具)

Doccano doccano 是一个面向人类的开源文本注释工具。它为文本分类、序列标记和序列到序列任务提供注释功能。您可以创建用于情感分析、命名实体识别、文本摘要等的标记数据。只需创建一个项目&#xff0c;上传数据&#xff0c;然后开始注释。您可以在数小时内构建数据集。 支持…...

03-使用一个不可变对象作为key,红黑树怎么比较大小?

使用一个不可变对象作为key&#xff0c;红黑树怎么比较大小&#xff1f; 答&#xff1a;Java 中的红黑树是通过左旋、右旋的方式来维护树的平衡性&#xff0c;而左旋、右旋又依赖于节点大小的比较。对于使用不可变对象作为key实际上是可以的&#xff0c;因为比较key的大小本身…...

2021江苏省赛热身赛 C Magic Rabbit(数形结合)

2021江苏省赛热身赛 C Magic Rabbit(数形结合) Magic Rabbit 非常好且巧妙地一道题。 大意&#xff1a;给出三种溶液 &#xff0c; 三种溶液分别含有不同浓度的 x &#xff0c;y 两种物质。 溶液x (mg/ml)y (mg/ml)溶液1x1y1溶液2x2y2溶液3x3y3 给出 Q 组询问 &#xff0c…...

AES加密(2):AES代码实现解析

在我的上一篇文章AES基础知识和计算过程中&#xff0c;大概介绍了AES(Rijndael)加密的整个过程。那么在这一篇文章中&#xff0c;就来看一下AES在代码中是如何实现的&#xff0c;也有助于我们理解其中的一些细节。 本篇文章所用的AES代码来源于Szymon Stefanek的开源C代码 文章…...

SpringBoot项目通过分词器生成词云

目录 前言一、词云是什么&#xff1f;二、使用步骤1.引入依赖2.application.yml3.Controller4.分词工具类4.词云生成工具类、支持输出文件和字节流 注意 前言 公司项目涉及到员工任务管理&#xff0c;需要从员工任务中获取任务信息生成个人词云图&#xff0c;可以把员工任务中…...

Nacos 配置管理及相关使用

文章目录 Nacos 配置管理一、统一配置管理1、在Nacos 中添加配置文件2、从微服务拉取配置3、配置实现步骤&#xff08;1&#xff09;引入 nacos-config 依赖&#xff08;2&#xff09;添加 bootstrap.yml&#xff08;4&#xff09;在 nacos 中添加配置 二、配置热更新1、配置热…...

重发布与路由策略

华子目录 重发布重发布条件重发布配置规则重发布名词配置命令ospf往rip重发布&#xff08;重发布动态&#xff09;静态往rip重发布&#xff08;重发布静态&#xff09;直连往rip重发布&#xff08;重发布直连&#xff09;rip往ospf重发布&#xff08;重发布动态&#xff09;静态…...

57. 插入区间(C++题解)

57. 插入区间 插入区间 给你一个无重叠的 &#xff0c;按照区间起始端点排序的区间列表。 在列表中插入一个新的区间&#xff0c;你需要确保列表中的区间仍然有序且不重叠&#xff08;如果有必要的话&#xff0c;可以合并区间&#xff09;。 示例 1&#xff1a; 输入&#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 中&#xff0c;循环依赖问题指的是两个或多个 bean 之间相互依赖形成的闭环。具体而言&#xff0c;当 bean A 依赖于 bean B&#xff0c;同时 bean B 也依赖于 bean A&#xff0c;就形成了循环依赖。 循环依赖问题在 Spring 容器中是一个非常常…...

【ArcGIS Pro二次开发】(65):进出平衡SHP转TXT、TXT转SHP

最近一个小伙伴提了这么一个需求&#xff0c;需要把TXT和SHP进行互转。 这种TXT文件其实遇到了好几个版本&#xff0c;都有一点小差异。之前已经做过一个TXT转SHP的工具&#xff0c;但好像不适用。于是针对这个版本&#xff0c;做了互转的2个工具。 【SHP转TXT】 一、要实现的…...

Shell开发实践:服务器的磁盘、CPU、内存的占用监控

&#x1f3c6;作者简介&#xff0c;黑夜开发者&#xff0c;CSDN领军人物&#xff0c;全栈领域优质创作者✌&#xff0c;CSDN博客专家&#xff0c;阿里云社区专家博主&#xff0c;2023年6月CSDN上海赛道top4。 &#x1f3c6;数年电商行业从业经验&#xff0c;历任核心研发工程师…...

超详细 async和await 项目实战运用(附加文字解答+源码)

文章目录 问题描述async什么是 asyncasync 的作用async 的应用场景async 优点 await什么是 awaitawait 的作用await 的应用场景await 的优点async和 await结合使用 结束语 大家好&#xff01;又到了愉快的周末假期&#xff0c;今天是2023年9月3日|农历七月十九&#xff0c;我最…...

Maven入门教程(三):Maven语法

视频教程&#xff1a;Maven保姆级教程 Maven入门教程(一)&#xff1a;安装Maven环境 Maven入门教程(二)&#xff1a;idea/Eclipse使用Maven Maven入门教程(三)&#xff1a;Maven语法 Maven入门教程(四)&#xff1a;Nexus私服 Maven入门教程(五)&#xff1a;自定义脚手架 6.Mav…...

C++技术点,故事解析

语言的魅力 从人类诞生开始 &#xff0c;南方古猿到现代人类经历了非常多变化&#xff1b; 南方古猿到能人 有什么变化&#xff1f; 能人会使用工具&#xff0c;由于会使用工具 就可以获得肉类食物&#xff0c;当然只能吃一些动物腐肉 直到进化成直立人的晚期&#xff0c;在东…...

数据结构(Java实现)-字符串常量池与通配符

字符串常量池 在Java程序中&#xff0c;类似于&#xff1a;1&#xff0c; 2&#xff0c; 3&#xff0c;3.14&#xff0c;“hello”等字面类型的常量经常频繁使用&#xff0c;为了使程序的运行速度更快、更节省内存&#xff0c;Java为8种基本数据类型和String类都提供了常量池。…...

python强化学习--gym安装与使用

最近开始学习强化学习&#xff0c;第一步肯定是要学会安装和使用pym&#xff0c;原本以为很简单&#xff0c;事实上确实很简单&#xff0c;但是遇到一个小问题&#xff0c;就是安装gym之后&#xff0c;在应用的过程中&#xff0c;游戏界面没有显示出来&#xff0c;了解后才知道…...

105. 从前序与中序遍历序列构造二叉树

给定两个整数数组 preorder 和 inorder &#xff0c;其中 preorder 是二叉树的先序遍历&#xff0c; inorder 是同一棵树的中序遍历&#xff0c;请构造二叉树并返回其根节点。 思路&#xff1a;题目给出了先序遍历和中序遍历的结果&#xff0c;因为先序遍历遵循根–>左–>…...

(第六天)初识Spring框架-SSM框架的学习与应用(Spring + Spring MVC + MyBatis)-Java EE企业级应用开发学习记录

SSM框架的学习与应用(Spring Spring MVC MyBatis)-Java EE企业级应用开发学习记录&#xff08;第六天&#xff09;初识Spring框架 ​ 昨天我们已经把Mybatis框架的基本知识全部学完&#xff0c;内容有Mybatis是一个半自动化的持久层ORM框架&#xff0c;深入学习编写动态SQL&a…...

内存分配函数malloc kmalloc vmalloc

内存分配函数malloc kmalloc vmalloc malloc实现步骤: 1)请求大小调整:首先,malloc 需要调整用户请求的大小,以适应内部数据结构(例如,可能需要存储额外的元数据)。通常,这包括对齐调整,确保分配的内存地址满足特定硬件要求(如对齐到8字节或16字节边界)。 2)空闲…...

C++实现分布式网络通信框架RPC(3)--rpc调用端

目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中&#xff0c;我们已经大致实现了rpc服务端的各项功能代…...

工业安全零事故的智能守护者:一体化AI智能安防平台

前言&#xff1a; 通过AI视觉技术&#xff0c;为船厂提供全面的安全监控解决方案&#xff0c;涵盖交通违规检测、起重机轨道安全、非法入侵检测、盗窃防范、安全规范执行监控等多个方面&#xff0c;能够实现对应负责人反馈机制&#xff0c;并最终实现数据的统计报表。提升船厂…...

MFC内存泄露

1、泄露代码示例 void X::SetApplicationBtn() {CMFCRibbonApplicationButton* pBtn GetApplicationButton();// 获取 Ribbon Bar 指针// 创建自定义按钮CCustomRibbonAppButton* pCustomButton new CCustomRibbonAppButton();pCustomButton->SetImage(IDB_BITMAP_Jdp26)…...

五年级数学知识边界总结思考-下册

目录 一、背景二、过程1.观察物体小学五年级下册“观察物体”知识点详解&#xff1a;由来、作用与意义**一、知识点核心内容****二、知识点的由来&#xff1a;从生活实践到数学抽象****三、知识的作用&#xff1a;解决实际问题的工具****四、学习的意义&#xff1a;培养核心素养…...

【单片机期末】单片机系统设计

主要内容&#xff1a;系统状态机&#xff0c;系统时基&#xff0c;系统需求分析&#xff0c;系统构建&#xff0c;系统状态流图 一、题目要求 二、绘制系统状态流图 题目&#xff1a;根据上述描述绘制系统状态流图&#xff0c;注明状态转移条件及方向。 三、利用定时器产生时…...

Axios请求超时重发机制

Axios 超时重新请求实现方案 在 Axios 中实现超时重新请求可以通过以下几种方式&#xff1a; 1. 使用拦截器实现自动重试 import axios from axios;// 创建axios实例 const instance axios.create();// 设置超时时间 instance.defaults.timeout 5000;// 最大重试次数 cons…...

多模态大语言模型arxiv论文略读(108)

CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文标题&#xff1a;CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文作者&#xff1a;Sayna Ebrahimi, Sercan O. Arik, Tejas Nama, Tomas Pfister ➡️ 研究机构: Google Cloud AI Re…...

【HarmonyOS 5 开发速记】如何获取用户信息(头像/昵称/手机号)

1.获取 authorizationCode&#xff1a; 2.利用 authorizationCode 获取 accessToken&#xff1a;文档中心 3.获取手机&#xff1a;文档中心 4.获取昵称头像&#xff1a;文档中心 首先创建 request 若要获取手机号&#xff0c;scope必填 phone&#xff0c;permissions 必填 …...

优选算法第十二讲:队列 + 宽搜 优先级队列

优选算法第十二讲&#xff1a;队列 宽搜 && 优先级队列 1.N叉树的层序遍历2.二叉树的锯齿型层序遍历3.二叉树最大宽度4.在每个树行中找最大值5.优先级队列 -- 最后一块石头的重量6.数据流中的第K大元素7.前K个高频单词8.数据流的中位数 1.N叉树的层序遍历 2.二叉树的锯…...