Kotlin基础知识学习(五)
Lambda表达式
Lambda表达式是一种简洁的方式来定义匿名函数。Kotlin的Lambda表达式非常灵活,常用于函数式编程、集合操作、高阶函数等场景。
无参数的Lambda表达式
格式:{函数体}
调用:{函数体}()
val greet = { println("Hello, Kotlin!") }greet() // 输出: Hello, Kotlin!
有参数的Lambda表达式
格式:{参数名:参数类型,参数名:参数类型… -> 函数体}
调用:{参数名:参数类型,参数名:参数类型… -> 函数体}(参数1,参数2…)
val sum = { a: Int, b: Int -> a + b }
println(sum(2, 3)) // 输出: 5
Lambda返回值
- 方法返回值由方法体最后一句语句决定。
val str = {println("Lambda返回值")"今天天气真好"}()println("$str")
Lambda 表达式作为函数参数
- Lambda 表达式可以作为函数的参数传递,这是函数式编程的重要特性之一。这种特性使得代码更加简洁、灵活。
基本用法
将 Lambda 作为最后一个参数
当 Lambda 表达式是函数的最后一个参数时,可以将其放在括号外面:
fun processNumbers(numbers: List<Int>, action: (Int) -> Unit) {for (number in numbers) {action(number)}
}fun main() {val numbers = listOf(1, 2, 3, 4, 5)// 常规调用方式processNumbers(numbers, { number -> println(number) })// Lambda 在括号外的简化写法processNumbers(numbers) { number -> println(number) }// 使用 it 简化单参数 LambdaprocessNumbers(numbers) { println(it) }
}
Lambda 作为唯一参数
如果函数只有一个 Lambda 参数,可以完全省略括号:
fun execute(action: () -> Unit) {action()
}fun main() {execute { println("Hello from Lambda!") }
}
高阶函数示例
Lambda 作为参数的高阶函数示例:
fun List.filterOnCondition(condition: (Int) -> Boolean): List {
val result = mutableListOf()
for (item in this) {
if (condition(item)) {
result.add(item)
}
}
return result
}
fun main() {
val numbers = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
// 过滤偶数
val evens = numbers.filterOnCondition { it % 2 == 0 }
println(evens) // [2, 4, 6, 8, 10]// 过滤大于5的数
val greaterThan5 = numbers.filterOnCondition { it > 5 }
println(greaterThan5) // [6, 7, 8, 9, 10]
}
Lambda 表达式函数参数用法
基本用法
返回 Lambda 表达式的基本语法
fun createGreeter(greeting: String): (String) -> String {return { name -> "$greeting, $name!" }
}fun main() {val englishGreeter = createGreeter("Hello")println(englishGreeter("Alice")) // 输出: Hello, Alice!val spanishGreeter = createGreeter("Hola")println(spanishGreeter("Bob")) // 输出: Hola, Bob!
}
直接返回 Lambda 表达式
可以省略返回类型声明,让编译器推断:
fun createMultiplier(factor: Int) = { number: Int -> number * factor }fun main() {val double = createMultiplier(2)println(double(5)) // 输出: 10val triple = createMultiplier(3)println(triple(5)) // 输出: 15
}
高级用法
返回带接收者的 Lambda
fun createStringBuilderAction(): StringBuilder.() -> Unit {return {append("Hello, ")append("World!")}
}fun main() {val action = createStringBuilderAction()val sb = StringBuilder()sb.action()println(sb.toString()) // 输出: Hello, World!
}
返回多个操作的组合 Lambda
fun createOperation(operator: String): (Int, Int) -> Int {return when (operator) {"add" -> { a, b -> a + b }"subtract" -> { a, b -> a - b }"multiply" -> { a, b -> a * b }else -> throw IllegalArgumentException("Unknown operator")}
}fun main() {val add = createOperation("add")println(add(5, 3)) // 输出: 8val multiply = createOperation("multiply")println(multiply(5, 3)) // 输出: 15
}
标准库中的高阶函数
集合基本查找函数
find / firstOrNull
- 返回第一个满足条件的元素,找不到则返回 null
- 两者功能完全相同,firstOrNull 语义更明确
Iterable<T>.find(predicate: (T) -> Boolean): T?
Iterable<T>.firstOrNull(predicate: (T) -> Boolean): T?
val numbers = listOf(1, 2, 3, 4, 5, 6, 7, 8)val firstEven = numbers.find { it % 2 == 0 } // 2
val firstOver10 = numbers.firstOrNull { it > 10 } // null
first
- 返回第一个满足条件的元素
- 找不到会抛出 NoSuchElementException
val firstOdd = numbers.first { it % 2 != 0 } // 1
// numbers.first { it > 10 } // 抛出 NoSuchElementException
last / lastOrNull
- 与 first 系列类似,但是从集合末尾开始查找
val lastEven = numbers.last { it % 2 == 0 } // 8
val lastUnder5 = numbers.lastOrNull { it < 5 } // 4
存在性检查函数
any
- 检查集合中是否存在至少一个满足条件的元素
val hasEven = numbers.any { it % 2 == 0 } // true
val hasNegative = numbers.any { it < 0 } // false
none
- 检查集合中是否没有任何元素满足条件
val noZeros = numbers.none { it == 0 } // true
val noEvens = numbers.none { it % 2 == 0 } // false
all
- 检查集合中所有元素是否都满足条件
val allPositive = numbers.all { it > 0 } // true
val allEven = numbers.all { it % 2 == 0 } // false
索引查找函数
indexOfFirst
- 返回第一个满足条件的元素的索引,找不到返回 -1
val firstEvenIndex = numbers.indexOfFirst { it % 2 == 0 } // 1
indexOfLast
- 返回最后一个满足条件的元素的索引,找不到返回 -1
val lastEvenIndex = numbers.indexOfLast { it % 2 == 0 } // 7
特殊查找函数
single
- 查找唯一满足条件的元素
- single 如果没有或找到多个会抛出异常
- singleOrNull 没有返回 null,多个也返回 null
val singleDigit = listOf(1, 2, 3).single { it == 2 } // 2
// listOf(1, 2, 3).single { it > 1 } // 抛出 IllegalArgumentExceptionval unique = listOf(1, 2, 3).singleOrNull { it == 4 } // null
takeWhile
- 从集合的第一个元素开始,顺序取出满足条件的元素,直到遇到第一个不满足条件的元素为止。
- 返回的是新集合(List)
- 原集合不会被修改
val numbers = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)val result = numbers.takeWhile { it < 5 }
println(result) // 输出: [1, 2, 3, 4]
filter
- 筛选出集合中所有满足条件的元素,与 takeWhile 不同,它会检查所有元素
- 返回满足条件的所有元素
- 原集合不会被修改
val numbers = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)val evenNumbers = numbers.filter { it % 2 == 0 }
println(evenNumbers) // 输出: [2, 4, 6, 8, 10]
- filterNot:筛选出不满足条件的元素
- filterIndexed:可以使用索引进行筛选
- filterIsInstance:按类型筛选
val mixedList = listOf(1, "two", 3, "four", 5.0)val strings = mixedList.filterIsInstance<String>()
println(strings) // 输出: [two, four]
count
- 统计集合中满足条件的元素数量。
- 返回的是满足条件的元素数量(Int)
- 比先 filter 再 size 更高效
- 无参数时返回集合大小
val numbers = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)val evenCount = numbers.count { it % 2 == 0 }
println(evenCount) // 输出: 5
standard库中的函数
repeat
- 简单的循环函数,用于重复执行某个操作指定的次数
/*
* @param times 重复次数
*
*/
repeat(times: Int, action: (Int) -> Unit)
repeat(3) {println("Hello") // 会打印3次"Hello"
}
- 第一个参数是重复次数(Int)
- 第二个参数是 Lambda 表达式(动作)
- 在 Lambda 中可以通过 it 访问当前迭代的索引(从0开始)
repeat(3) { index ->println("Iteration $index") // 打印 Iteration 0, Iteration 1, Iteration 2
}
run
- 有两种形式:扩展函数和非扩展函数。
- 扩展函数形式
T.run(block: T.() -> R): R
val result = "Hello".run {println(this) // "Hello" (this指向接收者)length // 返回值是Lambda的最后一行
}
println(result) // 5
- 非扩展函数形式
run(block: () -> R): R
val result = run {val x = 5val y = 3x + y // 返回值
}
println(result) // 8
let
- 扩展函数,主要用于在非空对象上执行操作。
val name: String? = "Kotlin"
name?.let {println(it) // "Kotlin" (it指向接收者)println(it.length) // 6
}
- 常用于空安全检查
- 参数是对象本身(用 it 引用)
- 返回 Lambda 的最后一行结果
apply
- 用于配置对象的属性,返回对象本身
val person = Person().apply {name = "Alice" // this.name = "Alice"age = 25 // this.age = 25
}
- 在 Lambda 中,this 指向接收者对象
- 返回接收者对象本身
- 常用于对象初始化
with
- 非扩展函数,允许在对象的上下文中执行代码块
val person = Person("Bob", 30)
val result = with(person) {println(name) // 可以直接访问属性println(age)"Name: $name, Age: $age" // 返回值
}
- 第一个参数是接收者对象
- 在 Lambda 中,this 指向接收者对象
- 返回 Lambda 的最后一行结果
相关文章:
Kotlin基础知识学习(五)
Lambda表达式 Lambda表达式是一种简洁的方式来定义匿名函数。Kotlin的Lambda表达式非常灵活,常用于函数式编程、集合操作、高阶函数等场景。 无参数的Lambda表达式 格式:{函数体} 调用:{函数体}() val greet { println("Hello, Kotl…...
搭建私人对外git空间
# 创建用户,指定不可登录的 Shell(git-shell 或 /usr/sbin/nologin) sudo adduser --system --shell /usr/bin/git-shell --group git # 验证用户配置 grep git /etc/passwd # 预期输出:git:x:998:998::/home/git:/usr/bin/git-s…...
5种特效融合愚人节搞怪病毒
内容供学习使用,不得转卖,代码复制后请1小时内删除,此代码会危害计算机安全,谨慎操作 并在虚拟机里运行此代码!,病毒带来后果自负! #include <windows.h> #include <cmath> #include <thread> using namespace std; // 屏幕特效函数声明 void In…...
DeepSeek本地部署(linux)
一、下载并安装Ollama 1.下载Ollama Ollama官网:Ollama 点击"Download",会跳转至下载页面。 1.1在线下载安装 可复制此命令到Linux服务器进行在线下载,如下载速度过慢,可选择离线下载安装。 curl -fsSL https://ollama.com/install.sh | sh1.2离线下载安装 …...
MySQL的基础语法1(增删改查、DDL、DML、DQL和DCL)
目录 一、基本介绍 二、SQL通用语法 三、SQL分类(DDL、DML、DQL、DCL) 1.DDL 1.1数据库操作 1.2表操作 1.2.1表操作-查询创建 1.2.2表操作-数据类型 1)数值类型 2)字符串类型 3)日期时间类型编辑 4)表操作-案例 1.2.3…...
Oracle数据库数据编程SQL<3.3 PL/SQL 游标>
游标(Cursor)是Oracle数据库中用于处理查询结果集的重要机制,它允许开发者逐行处理SQL语句返回的数据。 目录 一、游标基本概念 1. 游标定义 2. 游标分类 二、静态游标 (一)显式游标 【一】不带参数,普通的显示游标 1. 显式…...
畅享电脑流畅运行:深度卸载、智能监视与空间释放
软件介绍 在数字化办公与娱乐高度融合的当下,电脑承载着我们诸多重要任务,然而,随着软件的频繁安装与卸载,系统逐渐被各种顽固软件及其残留 “拖垮”,运行速度变慢、磁盘空间告急等问题接踵而至。别愁,今天…...
R --- Error in library(***) : there is no package called ‘***’ (服务器非root用户)
步骤 步骤一:在自己目录下创建R包安装路径步骤二:配置用户本地的R库路径步骤三:安装缺失的包(在终端)步骤四:验证安装 步骤一:在自己目录下创建R包安装路径 mkdir -p ~/R_libs步骤二࿱…...
Visual Studio Code 无法打开源文件解决方法
🌈 个人主页:Zfox_ 🔥 系列专栏:Linux 🔥 系列专栏:C从入门到精通 目录 一:🔥 突发状况 二:🔥 共勉 一:🔥 突发状况 🐬…...
核函数(机器学习深度学习)
一、核函数的基本概念 核函数(Kernel Function) 是机器学习中处理非线性问题的核心工具,通过隐式映射将数据从原始空间转换到高维特征空间,从而在高维空间中实现线性可分或线性建模。其数学本质是计算两个样本在高维空间中的内积…...
【工具】BioPred一个用于精准医疗中生物标志物分析的 R 软件包
介绍 R 语言包 BioPred 提供了一系列用于精准医疗中的亚组分析和生物标志物分析的工具。它借助极端梯度提升(XGBoost)算法,并结合倾向得分加权和 A 学习方法,帮助优化个体化治疗规则,从而简化亚组识别过程。BioPred 还…...
【银河麒麟系统常识】命令:dotnet --list-sdks(列出已安装的 .NET SDK 版本)
命令: dotnet --list-sdks 功能 列出当前系统中所有已安装的 .NET SDK 版本; 返回值规则 # 1. 格式:<版本号>[<安装路径>]; # 2. 排序:按版本号从低到高排序;示例...
【深度学习】不管理论,入门从手写数字识别开始
1. 环境安装 学习深度学习,开发语言是Python。Python开发工具有很多。其中 anaconda vscode的Python开发环境很好用,建议使用这个组合。 编写手写数字识别测试代码,需要在使用Anaconda安装以下4个库: NumpyScipymatplotlibsci…...
3.使用epoll实现单线程并发服务器
目录 1. epoll的概述 2. 多线程与epoll的处理流程 2.1 多线程处理流程 2.2 epoll处理流程 3. epoll与多线程的比较 4. epoll的操作函数 4.1 epoll_create() 4.2 epoll_ctl() 4.3 epoll_wait() 5. 示例代码 6. epoll的工作模式 7. 使用O_NONBLOCK防止阻塞 8.运行代…...
关于JVM和OS中的栈帧的区别和内存浅析
关于JVM和OS中的栈帧的区别和内存浅析 刚看了黑马JVM中的栈帧的讲解,感觉和自己理解的栈帧有一定出入,查询资料研究了一下发现的确有天壤之别,可惜黑马并没有讲。 故写下这篇文章巩固一下, OS的栈帧: OS的栈帧会在调用一个函…...
拥抱健康生活,开启养生之旅
在快节奏的现代生活中,健康养生愈发重要。它不仅能让我们拥有强健体魄,还能提升生活质量。 均衡饮食是养生的基石。多吃蔬菜和水果,它们富含维生素与膳食纤维。比如西兰花,堪称 “蔬菜皇冠”,不仅含有丰富的维生素 …...
测试用例管理工具
一、免费/开源工具 TestLink 适用场景:传统手工测试团队,需基础用例管理与测试计划跟踪。 关键功能:用例分层管理、执行结果记录、基础报告生成。 局限:界面陈旧,自动化集成需插件支持。 Kiwi TCMS 适用场景࿱…...
visual studio 2017配置QT5.9.4环境
前提是已经安装完毕vs 2017以及QT5.9.4,然后再进行下列的操作 一 环境配置 修改成如下所示,然后关闭vs 打开浏览器,搜索网站download.qt.io 如果2.4.1版本出现问题,可以换版本,如2.3.1,2.7.1都比较稳定 …...
基于EFISH-SBC-RK3576的无人机智能飞控与数据存储方案
一、方案背景 民用无人机在电力巡检、农业植保、应急救援等领域快速普及,但传统方案面临多协议设备兼容性差、野外环境数据易丢失、复杂电磁干扰三大痛点。 电鱼智能推出EFISH-SBC-RK3576,可集成双冗余总线接口与工业级加固存储&#x…...
c++的特性——多态
目录 概念 多态实现条件 虚函数 虚函数的重写/覆盖 练习题 析构函数的重写 override和final关键字 重载/隐藏/重载的区别 纯虚函数和抽象类 多态 虚函数表指针 多态的原理 动态绑定与静态绑定 虚函数表总结 前面学习了C的三个特性中的两个特性,今天我们…...
MySQL基础语法DDLDML
目录 #1.创建和删除数据库 #2.如果有lyt就删除,没有则创建一个新的lyt #3.切换到lyt数据库下 #4.创建数据表并设置列及其属性,name是关键词要用name包围 编辑 #5.删除数据表 #5.查看创建的student表 #6.向student表中添加数据,数据要与列名一一对应 #7.查询studen…...
性能测试理论基础-性能指标及jmeter中的指标
1、什么是性能测试 通过一定的手段,在多并发下情况下,获取被测系统的各项性能指标,验证被测系统在高并发下的处理能力、响应能力,稳定性等,能否满足预期。定位性能瓶颈,排查性能隐患,保障系统的质量,提升用户体验。 2、什么样的系统需要做性能测试 用户量大,页面访问…...
Postman CORS 测试完全指南:轻松模拟跨域请求,排查 CORS 相关问题
在使用 Postman 进行 API 测试时,通常不会遇到跨域问题,因为 Postman 是一个独立的客户端应用程序,不同于在浏览器中运行的 JavaScript 代码,它没有同源策略(SOP)的限制。跨域资源共享(CORS&…...
iOS抓包-charles和Stream
简单介绍几种抓包工具 1、Charles Charles是一款流行的跨平台HTTP代理软件,常用于Web调试,它可以帮助你在开发过程中检查、修改或模拟HTTP/HTTPS请求和响应。以下是如何在iOS设备上使用Charles进行抓包的基本步骤: 第一步:安装…...
三个核心文件:src\App.vue文件,index.html文件,src\main.js文件 的关系与运行流程解析(通俗形象)
一、三个文件的角色定位 用生活比喻理解它们的关系: index.html → “空房子” 像一栋毛坯房,只有基本的墙面和预留的插座(空白的HTML结构)。它的作用是提供一个容器,告诉Vue:“请把装修好的房间…...
云原生系列-K8S实战
K8S实战 1. K8S 资源创建方式2. NameSpace 资源创建3. Pod4. Deployment5. Service6. Ingress7. 存储抽象1. 环境准备2. PV&PVC1) 创建PV池2) PVC创建与绑定 3. ConfigMap 抽取应用配置,并且可以自动更新1) redis 示例2) 创建…...
从责任链模式聊到aware接口
从责任链模式聊到aware接口 责任链是什么? 责任链模式是一种行为型设计模式,将多个对象连接成一条链,并且沿着这条链传递请求,让多个对象都有机会处理这个请求,请求会顺着链传递,直到某个对象处理它为止。…...
ArcGIS地理信息系统空间分析实验教程学习
ArcGIS 作为地理信息系统领域的经典软件,以其强大的功能和广泛的应用场景,成为了众多学者、研究人员和专业人士的首选工具。它不仅可以高效地处理和可视化地理空间数据,还能通过复杂的空间分析模型,揭示地理现象背后的规律和趋势。…...
【3天!!!从0-1完成自动化集成平台开发--Cursor AI赋能0代码基础测试工程师开发平台-亲测有效-保姆级】
利用Cursor AI 赋能测试工程师从0-1开发自动化集成平台 ——含框架设计、实例代码与CI/CD集成 一、技术选型与框架设计1.1 核心框架选择1.2 整体架构图二、从0到1开发步骤2.1 初始化项目2.2 核心模块开发模块1:测试用例管理(Python)模块2:测试执行引擎(pytest)三、实战案…...
Compose 实践与探索十七 —— 多指手势与自定义触摸反馈
上一节我们讲了滑动的手势识别以及嵌套滑动,二者都属于触摸反馈这个大的范畴内的知识。本节我们将深入触摸反馈这个话题,讲一讲多指手势的识别与完全自定义的触摸反馈的实现。 1、多指手势 多指手势可以分为两类: 利用 API 处理预设好的手…...
