《Kotlin高阶函数完全指南:从入门到精通的15个核心函数》
2026/6/13 8:29:24 网站建设 项目流程

《Kotlin高阶函数完全指南:从入门到精通的15个核心函数》

  • 引言
  • 作用域函数
  • 集合操作函数
  • 延迟执行函数
  • 判断/检查函数
  • 内联函数 inline(核心重点)

引言

Kotlin 的高阶函数是其最强大的特性之一,它让代码更简洁、更具表现力。本文将基于实际代码示例,全面介绍 Kotlin 中的作用域函数、集合操作函数、延迟执行函数、判断检查函数以及内联函数,帮助你彻底掌握这些核心概念。

作用域函数

let — 空安全调用利器
let 在对象上下文中执行代码块,返回最后一行的结果,最常用于空安全调用。

/** * let:在对象上下文中执行代码块,返回最后一行结果,常用于空安全调用 */funletDemo(){valname="Kotlin"vallength=name.let{Log.d("MainActivity2",it)it.length}Log.d("MainActivity2","$length")}/** * let + 安全调用:仅在 user 不为 null 时执行 */funletDemo1(user:User?){user?.let{Log.d("MainActivity2","name:${it.name}")Log.d("MainActivity2","age:${it.age}")}}

run — 使用 this 作为上下文
run 与 let 类似,但使用 this 作为上下文引用,同样返回最后一行结果。

/** * run:类似 let,但直接使用 this 作为上下文,返回最后一行结果 */funrunDemo(user:User?){valfinalStr=user?.run{valfinalData="name:${user.name}age:${user.age}"finalData}Log.d("MainActivity2","finalStr:$finalStr")}

with — 非扩展函数形式
with 不是扩展函数,需要将对象作为参数传入,适用于对同一对象进行多次操作。

/** * with:非扩展函数,传入对象作为上下文,返回最后一行结果 */funwithDemo(name:String,age:Int):String{returnwith(StringBuilder()){append("姓名:")append(name)append(" ")append("年龄:")append(age)append("岁")toString()}}

apply — 对象初始化神器
apply 返回对象本身,非常适合用于初始化对象属性。

/** * apply:返回对象本身,常用于初始化对象属性 */funapplyDemo():User{returnUser().apply{name="Kotlin-Apply"age=15}}

also — 附加操作的好帮手
also 同样返回对象本身,常用于日志记录、调试等附加操作。

/** * also:返回对象本身,常用于附加操作如日志记录 */funalsoDemo(){valresult=User().also{Log.d("MainActivity2","开始记录")}.apply{name="Kotlin-Also"}.also{Log.d("MainActivity2","name:${it.name}")}.apply{age=15}.also{Log.d("MainActivity2","age:${it.age}")}Log.d("MainActivity2","最终的结果:$result")}

集合操作函数

map — 元素类型转换
将集合中的每个元素转换为另一种类型。

/** * map:将集合中的每个元素转换为另一种类型 */funmapDemo():List<Info>{valdataList=mutableListOf<User>()valuser1=User().apply{name="Kotlin"age=15}dataList.add(user1)valuser2=User().apply{name="Android"age=16}dataList.add(user2)valmapList=dataList.map{data->Info().apply{name=data.name age=data.age}}returnmapList}

filterNotNull — 过滤空值

/** * filterNotNull:过滤掉集合中的 null 元素 */funfilterDemo():List<User>{vallistData=listOf(User().apply{name="这是一个user"age=10},null)valfinalData=listData.filterNotNull()returnfinalData}

forEach — 遍历集合

/** * forEach:遍历集合并执行操作 */funforEachDemo(){vallistData=listOf(1,2,3,4,5)listData.forEach{Log.d("MainActivity2","$it")}}

reduce — 累积计算

/** * reduce:从第一个元素开始累积计算 */funreduceDemo():Int{// reduce: 从第一个元素开始累积valnumbers=listOf(1,2,3,4,5)valfinalData=numbers.reduce{acc,n->acc+n}returnfinalData}

groupBy — 分组

/** * groupBy:按条件分组,返回 Map */fungroupByDemo():List<Int>?{valnumbers=listOf(1,2,3,4,5,6,7,8,9,10)// 按奇偶分组valgroupedByParity=numbers.groupBy{if(it%2==0)"偶数"else"奇数"}valfinalData=groupedByParity["偶数"]returnfinalData}

sortedBy — 排序

/** * sortedBy:按指定规则排序 */funsortedByDemo():List<String>{valwords=listOf("Kotlin","Java","Python","Go","Rust")valbyLength=words.sortedBy{it.length}returnbyLength}

延迟执行函数

lazy — 懒加载
lazy 委托属性只在首次访问时才创建对象,常用于耗时的初始化操作。

/** * lazy:延迟初始化,首次访问时才创建对象 */funlazyDemo():User{valuserInfobylazy{User()}returnuserInfo}

repeat — 重复执行

/** * repeat:重复执行某段代码 n 次 */funrepeatDemo(){repeat(20){Log.d("MainActivity2","Hello Kotlin")}}

判断/检查函数

any
是否存在至少一个满足条件

/** * any:是否存在至少一个元素满足条件 */funanyDemo():Boolean{valnumbers=listOf(1,2,3,4,5)valhasEven=numbers.any{it%2==0}returnhasEven}

all
是否所有元素都满足条件

/** * all:是否所有元素都满足条件 */funallDemo():Boolean{valnumbers=listOf(2,4,6,8,10)valallEven=numbers.all{it%2==0}returnallEven}

none
是否没有元素满足条件

/** * none:是否没有元素满足条件 */funnoneDemo():Boolean{valnumbers=listOf(1,2,3,4,5)valnoEven=numbers.none{it%2==0}returnnoEven}

count
统计满足条件的元素个数

/** * count:统计满足条件的元素个数 */funcountDemo():Int{valnumbers=listOf(1,2,3,4,5,6,7,8,9,10)valevenCount=numbers.count{it%2==0}returnevenCount}

firstOrNull
查找第一个满足条件的元素

/** firstOrNull:查找第一个满足条件的元素,找不到返回 null */funfindDemo():Int?{valnumbers=listOf(1,2,3,4,5,6,7,8,9,10)valsameAsFirstOrNull=numbers.firstOrNull{it%2==0}returnsameAsFirstOrNull}

内联函数 inline(核心重点)

Lambda 的本质问题
普通的高阶函数在运行时,每次调用都会创建一个匿名函数对象(Lambda 对象),带来额外的内存开销和性能损耗。

// 普通高阶函数funoperateOnNumber(x:Int,operation:(Int)->Int):Int{returnoperation(x)}

编译后近似等价于:

vallambda=object:Function1<Int,Int>{overridefuninvoke(x:Int):Int=x*2}valresult=operateOnNumber(5,lambda)// 每次调用都创建对象

inline 解决方案
使用 inline 关键字,编译器会将函数体直接"内联"到调用处,消除 Lambda 对象的创建

inlinefunoperateOnNumber1(x:Int,operation:(Int)->Int):Int{returnoperation(x)}funinlineDemo(){valresult=operateOnNumber1(5){it*2}// 编译后代码会被内联为:val result = 5 * 2}

inline 的两大好处
消除 Lambda 对象创建 — 减少内存分配和 GC 压力
支持非局部返回 — 可以在 Lambda 中直接 return 外层函数

注意:inline 虽好,但不宜滥用。对于较大的函数体,内联会导致字节码膨胀,此时可考虑使用 noinline 或 crossinline。

掌握这些高阶函数,能让你的 Kotlin 代码更加简洁、优雅、高效。建议在实际开发中有意识地使用这些函数,逐步形成函数式编程思维。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询