Java 和 Kotlin Lambda 表达式详解

1. 什么是 Lambda 表达式?

Lambda 表达式是一种简洁的函数表达方式,可以把函数作为一个方法的参数,或者将代码块转换为数据传递。Lambda 表达式可以帮助减少样板代码,使代码更简洁、可读性更强。

2. Java Lambda 表达式
2.1 基本语法

Java 中的 Lambda 表达式语法如下:

(parameters) -> expression
(parameters) -> { statements; }
2.2 示例

一个简单的示例,使用 Lambda 表达式实现 Comparator 接口:

Comparator<String> comparator = (s1, s2) -> s1.compareTo(s2);
2.3 使用方法

1. 代替匿名类

// 使用匿名类
Runnable runnable = new Runnable() {@Overridepublic void run() {System.out.println("Hello, world!");}
};// 使用 Lambda 表达式
Runnable runnable = () -> System.out.println("Hello, world!");

2. 结合函数式接口
Java 中的 Lambda 表达式需要配合函数式接口使用,即仅包含一个抽象方法的接口,如 RunnableCallableComparator 等。

例如:

List<String> list = Arrays.asList("a", "b", "c");
list.forEach((String s) -> System.out.println(s));
2.4 注意事项
  1. Lambda 表达式不能脱离函数式接口单独存在。
  2. Lambda 表达式的类型在编译时会被推断为目标类型,即函数式接口的类型。
  3. Lambda 表达式中使用的变量必须是 final 或 effectively final。
3. Kotlin Lambda 表达式
3.1 基本语法

Kotlin 中的 Lambda 表达式语法如下:

{ parameters -> body }
3.2 示例

一个简单的示例,使用 Lambda 表达式排序一个字符串列表:

val list = listOf("banana", "apple", "cherry")
val sortedList = list.sortedBy { it.length }
println(sortedList) // 输出: [apple, banana, cherry]
3.3 使用方法

1. 代替匿名类
Kotlin 中的 Lambda 表达式可以用来代替匿名类:

// 使用匿名类
val runnable = object : Runnable {override fun run() {println("Hello, world!")}
}// 使用 Lambda 表达式
val runnable = Runnable { println("Hello, world!") }

2. 结合高阶函数
Kotlin 具有许多内置的高阶函数,如 mapfilterforEach 等,这些函数可以接受 Lambda 表达式作为参数。

例如:

val list = listOf(1, 2, 3, 4)
val doubled = list.map { it * 2 }
println(doubled) // 输出: [2, 4, 6, 8]
3.4 注意事项
  1. Kotlin 中的 Lambda 表达式可以作为变量,传递给函数或从函数返回。
  2. 可以使用带接收者的 Lambda 表达式,这允许在 Lambda 表达式内部调用接收者对象的方法。
  3. 使用 it 作为单个参数的默认名称,但也可以显式地命名参数。
4. 底层逻辑
4.1 Java 的实现

在 Java 中,Lambda 表达式编译后会生成一个与目标类型兼容的匿名类。Java 8 引入了 invokedynamic 字节码指令来支持 Lambda 表达式,这提高了 Lambda 表达式的性能。

4.2 Kotlin 的实现

在 Kotlin 中,Lambda 表达式被编译成匿名类,但 Kotlin 编译器会进行优化以减少匿名类的数量。Kotlin 的 Lambda 表达式也是基于 Java 的 invokedynamic 指令实现的,确保与 Java 平台的良好兼容性。

5. 示例项目

下面是一个 Java 和 Kotlin 混合的示例项目,展示如何使用 Lambda 表达式:

Java 代码:

public class Main {public static void main(String[] args) {List<String> list = Arrays.asList("apple", "banana", "cherry");list.forEach(s -> System.out.println(s));// 使用自定义函数式接口CustomFunctionalInterface custom = s -> System.out.println("Hello, " + s);custom.sayHello("world");}
}@FunctionalInterface
interface CustomFunctionalInterface {void sayHello(String name);
}

Kotlin 代码:

fun main() {val list = listOf("apple", "banana", "cherry")list.forEach { println(it) }// 使用自定义函数类型val custom: (String) -> Unit = { println("Hello, $it") }custom("world")
}

这个示例展示了如何在 Java 和 Kotlin 中使用 Lambda 表达式,如何结合函数式接口或高阶函数,以及如何编写跨语言的代码片段。希望对你有所帮助!

联系我

前面我有提到:Lambda 表达式不能脱离函数式接口单独存在。前面可能我说的不清楚,补充如下:
这句话的意思是,在 Java 中,lambda 表达式必须与一个函数式接口(functional interface)一起使用,不能单独存在。函数式接口是一个具有单一抽象方法(Single Abstract Method, SAM)的接口,它定义了 lambda 表达式的签名(即参数和返回类型)。

具体来说:

  1. 函数式接口定义
    一个函数式接口是一个仅包含一个抽象方法的接口。比如,java.util.function 包中的接口,如 Function<T, R>Consumer<T>Supplier<T> 等,都是函数式接口。你也可以定义自己的函数式接口:

    @FunctionalInterface
    public interface MyFunction {void execute();
    }
    
  2. lambda 表达式的使用
    Lambda 表达式是一种简洁的表达方式,用于实现函数式接口的抽象方法。例如:

    MyFunction myFunction = () -> System.out.println("Hello, World!");
    myFunction.execute();
    

    在上面的代码中,lambda 表达式 () -> System.out.println("Hello, World!") 实现了 MyFunction 接口的 execute 方法。lambda 表达式实际上是一个匿名方法,它只能在与函数式接口的实例一起使用时才有意义。

  3. 不能单独存在
    Lambda 表达式不能单独存在的原因是,它需要一个上下文来确定其参数和返回类型。函数式接口提供了这种上下文。脱离了函数式接口,lambda 表达式就无法确定其类型,也无法进行编译。

总结来说,lambda 表达式必须与函数式接口一起使用,函数式接口定义了 lambda 表达式的签名,使得 lambda 表达式可以作为函数式接口的实例进行使用。这就是为什么 lambda 表达式不能脱离函数式接口单独存在的原因。

联系我

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

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

相关文章

9种编程语言的对比分析

在当今的软件开发领域&#xff0c;编程语言扮演着至关重要的角色。不同的编程语言各有其特点和适用场景&#xff0c;选择合适的编程语言能够提高开发效率和软件质量。本文将对十种常见的编程语言进行对比分析&#xff0c;帮助读者了解它们的优缺点和适用场景。 Java 特点&…

freemarker 使用

首次使用freemarker遇到的全是坑,还好,各种问题,最终都解决了。芹菜加油 import com.lowagie.text.pdf.BaseFont; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.xhtmlrenderer.pdf.ITextRenderer;import java.io.Byte…

智能化软件开发微访谈·第三十一期 代码大模型训练、微调与增强

CodeWisdom “智能化软件开发沙龙是由CodeWisdom团队组织的围绕智能化软件开发、数据驱动的软件开发质量与效能分析、云原生与智能化运维等相关话题开展的线上沙龙&#xff0c;通过微信群访谈交流等线上交流方式将学术界与工业界专家学者汇聚起来&#xff0c;共同分享前沿研究进…

微软:Windows 11“跨设备服务“CPU占用率过高的错误确实存在

当某些后台任务导致电脑的 CPU 占用率过高时&#xff0c;通常意味着工作负载存在漏洞&#xff0c;从而导致其行为失常&#xff0c;而某些 Windows 进程或服务往往也是罪魁祸首。本月&#xff0c;Windows 用户和业内人士发现他们的系统出现了一些问题&#xff0c;通过使用方便的…

领夹麦克风哪个品牌音质最好?轻揭无线麦克风哪个品牌性价比高!

​随着短视频热潮的兴起&#xff0c;越来越多的人倾向于用vlog记录日常生活&#xff0c;同时借助短视频和直播平台开辟了副业。在这一过程中&#xff0c;麦克风在近两年内迅速发展&#xff0c;从最初的简单收音功能演变为拥有多样款式和功能&#xff0c;以满足视频创作的需求。…

【C++】AVL树/红黑树实现及map与set的封装

前言 【C】二叉树进阶&#xff08;二叉搜索树&#xff09; 这篇文章讲述了关于二叉搜索树知识&#xff0c;但是二叉搜索树有其自身的缺陷&#xff0c;假如往树中插入的元素有序或者接近有序&#xff0c;二叉搜索树就会退化成单支树&#xff0c;时间复杂度会退化成O(N)&#xff…

如何在Windows 10中恢复已删除的文件?

在 Windows 10 电脑上删除文件是一种常见的操作。如果你不需要某个文件&#xff0c;你会删除它。如果电脑空间用完了&#xff0c;你会尝试删除一些文件以释放更多空间。此外&#xff0c;你可以尝试清理电脑&#xff0c;使用电脑清理工具删除文件。 但是&#xff0c;如果您在 W…

如果供应商不能按时交货怎么办?

虽然说我们在采购的时候&#xff0c;我们会和供应商签订合同&#xff0c;合同上也会注明交期时间等一些必需的条件。 但是当供货商真的没有如期交货&#xff0c;或者交货拖延的时候&#xff0c;我们第一时间选择的是拿起法律武器来让对方承担违约责任吗? 显然&#xff0c;这选…

企业该如何实施ASPICE?

企业实施ASPICE以确保汽车软件和系统开发过程的质量&#xff0c;可以按照以下步骤进行&#xff1a; 一、明确目标和范围 确定评估的主要目的&#xff0c;例如过程改进、能力评定或合规性验证。 界定评估的范围&#xff0c;包括将涵盖的过程、项目和产品。 二、选择评估方法和…

Spring Cloud 常用组件(上)

Spring Cloud 是一个构建分布式系统的框架&#xff0c;它提供了许多解决微服务架构常见问题的工具和组件。Spring Cloud Netflix 是其中的一个子项目&#xff0c;集成了 Netflix 的开源软件来构建分布式系统。在这篇文章中&#xff0c;我们将详细介绍 Spring Cloud Netflix 的一…

地表位移监测系统:原理、组成与功能

地表位移监测系统是一项用于实时监测地表下沉、沉降、地面位移和地下水位变化的关键工具。本文将介绍该系统的工作原理、系统组成、工作模式以及功能特点&#xff0c;以便更深入地了解如何有效利用该系统进行沉降监测。 一、工作原理 地表位移监测系统主要由位移监测站、数据采…

揭秘未来:用线性回归模型预测一切的秘密武器!

线性回归模型 1. 引言2. 理论基础2.1 线性回归模型的定义与原理原理与关键假设模型参数估计 2.2 模型评估指标2.2.1 残差分析2.2.2 拟合优度指标2.2.3 统计检验 3. 应用场景3.1. 金融领域中的应用3.2. 医疗健康领域中的应用3.3. 其他领域的应用 4. 实例分析4.1、数据集选择4.2、…

服务器数据恢复—OceanStor存储中NAS卷数据丢失如何恢复数据?

服务器存储数据恢复环境&故障&#xff1a; 华为OceanStor某型号存储。工作人员在上传数据时发现该存储上一个NAS卷数据丢失&#xff0c;管理员随即关闭系统应用&#xff0c;停止上传数据。这个丢失数据的卷中主要数据类型为office文件、PDF文档、图片文件&#xff08;JPG、…

❤ npm运行打包报错归纳

❤ 前端运行打包报错归纳 &#xff08;安装依赖&#xff09;Cannot read property ‘pickAlgorithm’ of null" npm uninstall //删除项目下的node_modules文件夹 npm cache clear --force //清除缓存后 npm install //重新安装 备用安装方式 npm install with --for…

微信小程序添加服务类目|《非经营性互联网信息服务备案核准》怎么获取

根据客服反馈&#xff0c;《非经营性互联网信息服务备案核准》在工业和信息化部政务服务平台网站查询&#xff0c;查询结果的截图就是《非经营性互联网信息服务备案核准》。 工业和信息化部政务服务平台 《非经营性互联网信息服务备案核准》&#xff1a; 与客服聊天的截图&a…

SpringBoot如何自定义启动Banner 以及自定义启动项目控制台输出信息 类似于若依启动大佛 制作教程

前言 Spring Boot 项目启动时会在控制台打印出一个 banner&#xff0c;下面演示如何定制这个 banner。 若依也会有相应的启动动画 _ooOoo_o8888888o88" . "88(| -_- |)O\ /O____/---\____. \\| |// ./ \\||| : |||// \/ _||||| -:- |||||- \| | \\…

第二十一章 访问者模式

目录 1 访问者模式介绍 2 访问者模式原理 3 访问者模式实现 4 访问者模式总结 1 访问者模式介绍 访问者模式(Visitor Pattern) 的原始定义是&#xff1a;允许在运行时将一个或多个操作应用于一组对象&#xff0c;将操作与对象结构分离 2 访问者模式原理 抽象访问者&#xf…

python爬虫之JS逆向——并发爬虫

一、进程、线程以及协程的概念 1 进程 进程是一个具有一定独立功能的程序在一个数据集上的一次动态执行的过程&#xff0c;是操作系统进行资源分配和调度的一个独立单位&#xff0c;是应用程序运行的载体 跑起来的程序才叫进程 多道技术&#xff1a;空间复用时间复用&#…

DS18B20温度传感器完整使用介绍(配合51单片机)

DS18B20是一款由Maxim Integrated&#xff08;原Dallas Semiconductor&#xff09;生产的数字温度传感器&#xff0c;以其高精度、低功耗、灵活的接口方式和易于使用的特性&#xff0c;在各种温度监测应用中被广泛采用。 以下是DS18B20的详细介绍&#xff1a; 基本特性 数字输…

C++的map

作用&#xff1a; 映射&#xff0c;相当于python的字典&#xff0c;使用一个key来寻找value&#xff0c;m[key]value; 生成&#xff1a; map<int,string> m;//无参生成&#xff0c;key是int类型&#xff0c;value是string类型 map<int,string> m{{1,"hello…