Java8新特性(一) Lambda表达式与函数式接口

Java8新特性(一) Lambda表达式与函数式接口

一. 基本概念

Lambda表达式是Java 8中引入的一个重要的新特性,该表达式提出了一种新的语法规则,用于对某些(函数式接口)匿名内部类的书写方式进行简化。除此之外,Lambda表达式是函数式编程思想的一个重要体现,它允许我们通过表达式的形式来定义和传递功能,并且更加关注数据本身。以线程创建为例,Lambda表达式的基本语法规则如下:(参数列表)->{ 方法体(代码); }

//1. Runnable匿名内部类
new Thread(new Runnable() {@Overridepublic void run() {System.out.println("Thread running...");}
}).start();
//2. Runnable Lambda表达式
new Thread(()->{System.out.println("Thread running...");
}).start();

二. 语法特性

1. 限制条件

(1)Lambda表达式只能用于简化函数式接口的匿名内部类的实现,即只含有一个抽象方法的接口(可以包含默认default方法),或者是声明了 @FunctionalInterface 注解的接口。注意:Lambda表达式不能够简化类或者抽象类的创建,如果试图使用Lambda表达式去创建一个类或者抽象类将会报错如下 ”Target type of a lambda conversion must be an interface“;

(2)Lambda表达式可以看作是一种特殊的匿名内部类的实现,也被称为匿名函数,匿名内部类的所有使用限制都会对其生效;

2. 省略规则

(1)参数列表中的参数类型可以省略,JVM编译器可以通过上下文自动做"类型推断",但是所有参数类型是否省略必须统一;

  • 参数列表中若只有一个参数,则可以省略参数列表的小括号(同时必须省略参数类型);

  • 参数列表中若没有参数(即无参抽象方法),则参数列表的小括号不可省略;

(2)若方法体中只有一句代码,则方法体的大括号可以省略(包括结尾分号);若该代码是return语句,则在省略大括号时必须进一步去掉return关键字;

(3)若方法体由多句代码组成,则方法体格式必须完整;

// 1.保留参数类型
(int x,int y) -> {int res = x + y;return res;
}// 2.省略参数类型
(x,y) -> { int res = x + y; return res;
}// 3.只有一个参数(无返回值)
x -> {int res = x * x;System.out.print(res);
}// 4.无参数
() -> {System.out.print("无参表达式");}// 5.单行方法体-返回其2倍的值
x -> 2 * x// 6.单行方法体-返回他们的差值  
(x, y) -> x – y // 7.单行方法体-无返回值
(String str) -> System.out.print(str)

3.变量捕获

类似于匿名内部类,Lambda表达式同样可以捕获外部作用域中的变量数据,并可以直接使用这些变量而无需声明。Lambda表达式可以捕获的变量数据类型如下:

  • 实例变量(Instance Variables):若Lambda表达式定义在非静态域中,则可以捕获并访问包含它的实例的成员实例变量,并可以使用OuterClass.this关键字来指明外部类的引用;

  • 静态变量(Static Variables):Lambda表达式定义在静态/非静态域中都可以随时捕获并访问包含它的类的成员静态变量;

  • 方法参数(Method Parameters):Lambda表达式可以捕获并访问包含它的方法的参数,本质上与本地局部变量一致;

  • 本地变量(Local Variables):Lambda表达式可以捕获并访问声明为final的本地局部变量。从Java 8开始,final关键字可以省略(自动添加),但该变量的值实际上不可修改(该表达式域内外均不可修改);

在Lambda表达式中捕获的成员变量(实例变量、静态变量)与其在外部作用域中发生的改变将会同步;但方法参数和本地局部变量经由Lambda表达式访问之后,就会添加final修饰,此时变量的值在表达式域的内外均已不可修改。

public class LambdaDemo01 {private int instanceVariable = 10;private static int staticVariable = 20;public static void staticMethod(int methodVariable){int localVar = 30;// 静态域中 Lambda表达式捕获外部变量Runnable runnable = () -> {staticVariable += 1; //修改外部类静态成员// methodVariable += 1; //error: Variable used in lambda expression should be final or effectively final// localVar += 1; //error: Variable used in lambda expression should be final or effectively finalSystem.out.println("Static variable: " + staticVariable);System.out.println("Method variable: " + methodVariable);System.out.println("Local variable: " + localVar);};runnable.run();}public void instanceMethod(int methodVariable){int localVar = 30;// 非静态域中 Lambda表达式捕获外部变量Runnable runnable = () -> {instanceVariable += 1; //修改外部类实例成员System.out.println("Instance variable: " + LambdaDemo01.this.instanceVariable); //LambdaDemo01.this外部类引用System.out.println("Static variable: " + staticVariable);System.out.println("Method variable: " + methodVariable);System.out.println("Local variable: " + localVar);};instanceVariable += 2; //synchronous changerunnable.run();}public static void main(String[] args) {LambdaDemo01.staticMethod(40);LambdaDemo01 lambdaDemo01 = new LambdaDemo01();lambdaDemo01.instanceMethod(40);}
}

4.应用场景

4.1 简化函数式接口

Lambda表达式提供了一种更简洁、更便捷的方式来声明匿名函数(函数式接口的实例),这使得Java语言更加灵活,是Java函数式编程的实现基础,另一方面它也使得代码更为紧凑、简洁,并提高了可读性、减少了代码冗余。

4.2 配合Stream API

Java 8新特性中的Stream API(java.util.stream) 是一种抽象流式接口,其是一个来自数据源的元素队列并支持一系列聚合操作,比如过滤、筛选、映射、遍历等;Stream可以以一种声明的方式处理集合与数据,是函数式编程模式的重要体现。Lambda表达式常用于配合Stream API实现各种数据处理操作,使得数据处理更加简洁、直观。

public interface Stream<T> extends BaseStream<T, Stream<T>> {/*** Returns a stream consisting of the elements of this stream that match* the given predicate.** <p>This is an <a href="package-summary.html#StreamOps">intermediate* operation</a>.** @param predicate a <a href="package-summary.html#NonInterference">non-interfering</a>,*                  <a href="package-summary.html#Statelessness">stateless</a>*                  predicate to apply to each element to determine if it*                  should be included* @return the new stream*/Stream<T> filter(Predicate<? super T> predicate);/*** Returns a stream consisting of the results of applying the given* function to the elements of this stream.** <p>This is an <a href="package-summary.html#StreamOps">intermediate* operation</a>.** @param <R> The element type of the new stream* @param mapper a <a href="package-summary.html#NonInterference">non-interfering</a>,*               <a href="package-summary.html#Statelessness">stateless</a>*               function to apply to each element* @return the new stream*/<R> Stream<R> map(Function<? super T, ? extends R> mapper);//...
}

4.3 简化集合操作

在Java 8及以上的版本中,为了能够让Lambda表达式和Java的集合类集更好的配合使用,集合Collection接口新增了一些默认方法,例如forEach()removeIf()stream()等,这使得使用Lambda表达式更加方便、数据处理更加高效。此处以集合遍历forEach()操作为例,介绍如下:

(1)List

//1.List forEach 源码
default void forEach(Consumer<? super T> action) {Objects.requireNonNull(action);for (T t : this) {action.accept(t);}
}
//2.example
List<String> names = Arrays.asList("Alice", "Bob", "Tom","Krito");
// 参数不固定为t,其他参数名称也可以(name)
names.forEach(name -> {int len = name.length();System.out.println(name + " with length = " + len);
});

(2)Map

//1.Map forEach 源码
default void forEach(BiConsumer<? super K, ? super V> action) {Objects.requireNonNull(action);for (Map.Entry<K, V> entry : entrySet()) {K k;V v;try {k = entry.getKey();v = entry.getValue();} catch(IllegalStateException ise) {// this usually means the entry is no longer in the map.throw new ConcurrentModificationException(ise);}action.accept(k, v);}
}
//2.example
Map<String, Integer> ages = new HashMap<>();
ages.put("Alice", 25);
ages.put("Bob", 22);
ages.put("Tom", 27);
ages.put("Krito",25);
// 双参数
ages.forEach((key, value) -> System.out.println(key + " : " + value));

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/51462.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

什么是等保测评?

信息安全等级保护测评&#xff0c;简称等保测评&#xff0c;是根据我国《信息安全等级保护管理办法》的规定&#xff0c;对国家重要信息系统进行的安全评估制度。等保测评的频率、必要性以及在实际操作中的常见误区&#xff0c;是企业和机构在进行等保测评时需要了解的重要内容…

智能写作分享

智能写作技术路线 ​ 在大模型的现有能力框架内&#xff0c;其对于处理长文档级别的智能写作任务存在一定的局限性。针对这一问题&#xff0c;本文深入探讨了长文档智能写作这一应用场景&#xff0c;并在此基础上&#xff0c;提出了一套切实可行的技术解决方案。该方案旨在弥补…

ts踩坑!使用可选链 ?.处理可能遇到的 undefined 或 null 值的情况,但是仍然收到一个关于可能为 undefined 的警告!

在 TypeScript 中&#xff0c;当你使用可选链&#xff08;Optional Chaining&#xff09;?. 时&#xff0c;你其实已经处理了可能遇到的 undefined 或 null 值的情况。但是&#xff0c;如果你仍然收到一个关于可能为 undefined 的警告&#xff0c;这可能是因为 TypeScript 的类…

关于js函数参数是否会实时更新的问题

遇到一个小问题 export function test001(value, callback) {setTimeout(() > {if (value undefined) {test001(value, callback)} else {callback()}}, 100) }// 调用处 // 要测试的变量 param01 test001(param01, () > {console.log(值不为空啦) }) 这个变量param01…

指针的意义

/指针------------------------------------------------------------------------------------------ // 1&#xff0c;指针是---------- // 通过它能找到以它为地址的内存单元 //int main() //{ // int a 10;//开辟一块空间 // int* p &a;//将变量a的地址取出&…

web自动化6-pytest③实践测试用例-回归用例web自动化

# -*- coding: utf-8 -*- """ lemut_select - 业务受理 Author: duxiaowei Date: 2024/7/17 """ import timeimport allure import pytest from selenium.webdriver.common.by import By# 业务受理 allure.feature("业务受理") class …

Unity Apple Vision Pro 开发:如何把 PolySpatial 和 Play To Device 的版本从 1.2.3 升级为 1.3.1

XR 开发社区&#xff1a; SpatialXR社区&#xff1a;完整课程、项目下载、项目孵化宣发、答疑、投融资、专属圈子 &#x1f4d5;教程说明 本教程将介绍如何把 Unity 的 PolySpatial 和 Play To Device 版本从 1.2.3 升级为 1.3.1。 &#x1f4d5;Play To Device 软件升级 ht…

使用 Visual Studio 2022 自带的 cl.exe 编译 tensorRT自带测试样例 sampleOnnxMNIST

1. 新建任意文件夹&#xff0c;将 D:\install\tensorRT\TensorRT-8.6.1.6\samples\sampleOnnxMNIST 下面的 sampleOnnxMNIST.cpp 文件复制进来&#xff0c;同时 D:\install\tensorRT\TensorRT-8.6.1.6\samples\sampleOnnxMNIST 下面的 sample_onnx_mnist.vcxproj 中的内容&…

Java核心 - 内部类详解

作者&#xff1a;逍遥Sean 简介&#xff1a;一个主修Java的Web网站\游戏服务器后端开发者 主页&#xff1a;https://blog.csdn.net/Ureliable 觉得博主文章不错的话&#xff0c;可以三连支持一下~ 如有疑问和建议&#xff0c;请私信或评论留言&#xff01; 前言 在Java编程中&a…

vite5-macos仿macOS网页osx管理系统|vue3+arcoDesign桌面os

基于vite5.xvue3arco-design原创自研网页版os管理框架ViteWebOS。 使用最新前端技术vite5vue3pinia2arcoDesignsortablejsecharts搭建网页pc版桌面os式后台管理系统解决方案。支持自定义桌面栅格布局引擎、可拖拽桌面图标、多屏分页管理、自定义桌面壁纸主题、毛玻璃虚化背景等…

学Java一篇文章就够了(手把手教你入门)

第11章 枚举&注解&内部类 一、枚举 概念 枚举类型是Java 5中新增特性的⼀部分&#xff0c;它是⼀种特殊的数据类型&#xff0c;之所以特殊是因为它既是⼀种类 (class)类型却⼜⽐类类型多了些特殊的约束&#xff0c;但是这些约束的存在也造就了枚举类型的简洁性、安…

51单片机----开发工具介绍及软件安装

目录 一、硬件工具 二、软件工具 三、软件安装 四、总结 51单片机作为经典的入门级微控制器&#xff0c;因其易学易用、性价比高的特点&#xff0c;被广泛应用于各种电子产品中。想要玩转51单片机&#xff0c;首先需要了解其开发工具和软件安装方法。本文将从硬件和软件两方…

JCR一区级 | Matlab实现TTAO-Transformer-LSTM多变量回归预测

JCR一区级 | Matlab实现TTAO-Transformer-LSTM多变量回归预测 目录 JCR一区级 | Matlab实现TTAO-Transformer-LSTM多变量回归预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.【JCR一区级】Matlab实现TTAO-Transformer-LSTM多变量回归预测&#xff0c;三角拓扑聚合…

C语言 #具有展开功能的排雷游戏

文章目录 前言 一、整个排雷游戏的思维梳理 二、整体代码分布布局 三、游戏主体逻辑实现--test.c 四、整个游戏头文件的引用以及函数的声明-- game.h 五、游戏功能的具体实现 -- game.c 六、老六版本 总结 前言 路漫漫其修远兮&#xff0c;吾将上下而求索。 一、整个排…

【OSCP系列】OSCP靶机-BTRsys-2.1(原创)

OSCP系列靶机—BTRsys-2.1 原文转载已经过授权 原文链接&#xff1a;Lusen的小窝 - 学无止尽&#xff0c;不进则退 (lusensec.github.io) 一、主机发现 二、端口扫描 1、快速扫描 2、全端口扫描 3、服务系统探测 4、漏洞探测 80端口扫到了一些目录&#xff0c;有wordpress框…

Paimon数据湖详解(第49天)

系列文章目录 一. Paimon数据湖增删改查 二. 查询优化 三. 系统表 四. Lookup Joins 文章目录 系列文章目录前言Paimon数据湖的使用1、创建Table1.1 创建catalog管理的表1.2 分区表1.3 Create Table As&#xff08;了解&#xff09;1.4 Create Table Like1.5 表属性1.6 创建外…

无心剑中译莎士比亚《爱如星辰引迷舟》

莎士比亚十四行诗第116首 Sonnet 116 爱如星辰引迷舟 Let me not to the marriage of true minds Admit impediments. Love is not love Which alters when it alteration finds, Or bends with the remover to remove: O, no! it is an ever-fixed mark That looks on tempe…

C++(week14): C++提高:(一)面向对象设计:设计原则、设计模式

文章目录 一、面向对象设计的概念4.统一建模语言&#xff1a;UML语言StartUML 二、类与类之间的关系0.总结(1)类与类的五种关系(2)区别(3)面向对象 vs 基于对象 1.继承 (泛化耦合)2.组合 (Composition)3.聚合 (Aggregation)4.关联(1)双向关联(2)单向关联 5.依赖 (Dependency) 三…

简单几步,把浏览器书签转换成导航网页

废话不多说直奔主题上干货 Step 1 下载浏览器书签 1&#xff0c;电脑浏览器点击下载Pintree Pintree 是一个开源项目&#xff0c;旨在将浏览器书签导出成导航网站。通过简单的几步操作&#xff0c;就可以将你的书签转换成一个美观且易用的导航页面。 2. 安装 Pintree B…

常见OVS网桥及其链接接口详解

目录 引言OVS简介常见OVS网桥 QBR&#xff08;qbr&#xff09;PLY网桥br-intbr-tunbr-routerbrcps常见网桥链接接口 QVOQVIQVMPatch网桥和接口的工作原理应用场景 虚拟化环境数据中心网络云计算平台 1. 引言 开放虚拟交换机&#xff08;Open vSwitch&#xff0c;简称OVS&…