当前位置: 首页 > 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…...

以下是对华为 HarmonyOS NETX 5属性动画(ArkTS)文档的结构化整理,通过层级标题、表格和代码块提升可读性:

一、属性动画概述NETX 作用&#xff1a;实现组件通用属性的渐变过渡效果&#xff0c;提升用户体验。支持属性&#xff1a;width、height、backgroundColor、opacity、scale、rotate、translate等。注意事项&#xff1a; 布局类属性&#xff08;如宽高&#xff09;变化时&#…...

Day131 | 灵神 | 回溯算法 | 子集型 子集

Day131 | 灵神 | 回溯算法 | 子集型 子集 78.子集 78. 子集 - 力扣&#xff08;LeetCode&#xff09; 思路&#xff1a; 笔者写过很多次这道题了&#xff0c;不想写题解了&#xff0c;大家看灵神讲解吧 回溯算法套路①子集型回溯【基础算法精讲 14】_哔哩哔哩_bilibili 完…...

成都鼎讯硬核科技!雷达目标与干扰模拟器,以卓越性能制胜电磁频谱战

在现代战争中&#xff0c;电磁频谱已成为继陆、海、空、天之后的 “第五维战场”&#xff0c;雷达作为电磁频谱领域的关键装备&#xff0c;其干扰与抗干扰能力的较量&#xff0c;直接影响着战争的胜负走向。由成都鼎讯科技匠心打造的雷达目标与干扰模拟器&#xff0c;凭借数字射…...

ArcGIS Pro制作水平横向图例+多级标注

今天介绍下载ArcGIS Pro中如何设置水平横向图例。 之前我们介绍了ArcGIS的横向图例制作&#xff1a;ArcGIS横向、多列图例、顺序重排、符号居中、批量更改图例符号等等&#xff08;ArcGIS出图图例8大技巧&#xff09;&#xff0c;那这次我们看看ArcGIS Pro如何更加快捷的操作。…...

JVM暂停(Stop-The-World,STW)的原因分类及对应排查方案

JVM暂停(Stop-The-World,STW)的完整原因分类及对应排查方案,结合JVM运行机制和常见故障场景整理而成: 一、GC相关暂停​​ 1. ​​安全点(Safepoint)阻塞​​ ​​现象​​:JVM暂停但无GC日志,日志显示No GCs detected。​​原因​​:JVM等待所有线程进入安全点(如…...

零基础在实践中学习网络安全-皮卡丘靶场(第九期-Unsafe Fileupload模块)(yakit方式)

本期内容并不是很难&#xff0c;相信大家会学的很愉快&#xff0c;当然对于有后端基础的朋友来说&#xff0c;本期内容更加容易了解&#xff0c;当然没有基础的也别担心&#xff0c;本期内容会详细解释有关内容 本期用到的软件&#xff1a;yakit&#xff08;因为经过之前好多期…...

React---day11

14.4 react-redux第三方库 提供connect、thunk之类的函数 以获取一个banner数据为例子 store&#xff1a; 我们在使用异步的时候理应是要使用中间件的&#xff0c;但是configureStore 已经自动集成了 redux-thunk&#xff0c;注意action里面要返回函数 import { configureS…...

用机器学习破解新能源领域的“弃风”难题

音乐发烧友深有体会&#xff0c;玩音乐的本质就是玩电网。火电声音偏暖&#xff0c;水电偏冷&#xff0c;风电偏空旷。至于太阳能发的电&#xff0c;则略显朦胧和单薄。 不知你是否有感觉&#xff0c;近两年家里的音响声音越来越冷&#xff0c;听起来越来越单薄&#xff1f; —…...

VM虚拟机网络配置(ubuntu24桥接模式):配置静态IP

编辑-虚拟网络编辑器-更改设置 选择桥接模式&#xff0c;然后找到相应的网卡&#xff08;可以查看自己本机的网络连接&#xff09; windows连接的网络点击查看属性 编辑虚拟机设置更改网络配置&#xff0c;选择刚才配置的桥接模式 静态ip设置&#xff1a; 我用的ubuntu24桌…...

Kafka入门-生产者

生产者 生产者发送流程&#xff1a; 延迟时间为0ms时&#xff0c;也就意味着每当有数据就会直接发送 异步发送API 异步发送和同步发送的不同在于&#xff1a;异步发送不需要等待结果&#xff0c;同步发送必须等待结果才能进行下一步发送。 普通异步发送 首先导入所需的k…...