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

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

引言

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

作用域函数

let --- 空安全调用利器

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

kotlin 复制代码
 /**
     * let:在对象上下文中执行代码块,返回最后一行结果,常用于空安全调用
     */
    fun letDemo() {
        val name = "Kotlin"
        val length = name.let {
            Log.d("MainActivity2", it)
            it.length
        }
        Log.d("MainActivity2", "$length")
    }

    /**
     * let + 安全调用:仅在 user 不为 null 时执行
     */
    fun letDemo1(user: User?) {
        user?.let {
            Log.d("MainActivity2", "name:${it.name}")
            Log.d("MainActivity2", "age:${it.age}")
        }
    }

run --- 使用 this 作为上下文

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

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

with --- 非扩展函数形式

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

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

apply --- 对象初始化神器

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

kotlin 复制代码
/**
     * apply:返回对象本身,常用于初始化对象属性
     */
    fun applyDemo(): User {
        return User().apply {
            name = "Kotlin-Apply"
            age = 15
        }
    }

also --- 附加操作的好帮手

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

kotlin 复制代码
/**
     * also:返回对象本身,常用于附加操作如日志记录
     */
    fun alsoDemo() {
        val result = 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 --- 元素类型转换

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

kotlin 复制代码
/**
     * map:将集合中的每个元素转换为另一种类型
     */
    fun mapDemo(): List<Info> {
        val dataList = mutableListOf<User>()
        val user1 = User().apply {
            name = "Kotlin"
            age = 15
        }

        dataList.add(user1)

        val user2 = User().apply {
            name = "Android"
            age = 16
        }

        dataList.add(user2)

        val mapList = dataList.map { data ->
            Info().apply {
                name = data.name
                age = data.age
            }
        }

        return mapList
    }

filterNotNull --- 过滤空值

kotlin 复制代码
/**
     * filterNotNull:过滤掉集合中的 null 元素
     */
    fun filterDemo(): List<User> {
        val listData = listOf(User().apply {
            name = "这是一个user"
            age = 10
        }, null)

        val finalData = listData.filterNotNull()
        return finalData
    }

forEach --- 遍历集合

kotlin 复制代码
/**
     * forEach:遍历集合并执行操作
     */
    fun forEachDemo() {
        val listData = listOf(1, 2, 3, 4, 5)
        listData.forEach {
            Log.d("MainActivity2", "$it")
        }
    }

reduce --- 累积计算

kotlin 复制代码
/**
     * reduce:从第一个元素开始累积计算
     */
    fun reduceDemo(): Int {
        // reduce: 从第一个元素开始累积
        val numbers = listOf(1, 2, 3, 4, 5)
        val finalData = numbers.reduce { acc, n -> acc + n }
        return finalData
    }

groupBy --- 分组

kotlin 复制代码
/**
     * groupBy:按条件分组,返回 Map
     */
    fun groupByDemo(): List<Int>? {
        val numbers = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
        // 按奇偶分组
        val groupedByParity = numbers.groupBy { if (it % 2 == 0) "偶数" else "奇数" }
        val finalData = groupedByParity["偶数"]
        return finalData
    }

sortedBy --- 排序

kotlin 复制代码
/**
     * sortedBy:按指定规则排序
     */
    fun sortedByDemo(): List<String> {
        val words = listOf("Kotlin", "Java", "Python", "Go", "Rust")
        val byLength = words.sortedBy { it.length }
        return byLength
    }

延迟执行函数

lazy --- 懒加载

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

kotlin 复制代码
/**
     * lazy:延迟初始化,首次访问时才创建对象
     */
    fun lazyDemo(): User {
        val userInfo by lazy { User() }
        return userInfo
    }

repeat --- 重复执行

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

判断/检查函数

any

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

kotlin 复制代码
/**
     * any:是否存在至少一个元素满足条件
     */
    fun anyDemo(): Boolean {
        val numbers = listOf(1, 2, 3, 4, 5)
        val hasEven = numbers.any { it % 2 == 0 }
        return hasEven
    }

all

是否所有元素都满足条件

kotlin 复制代码
/**
     * all:是否所有元素都满足条件
     */
    fun allDemo(): Boolean {
        val numbers = listOf(2, 4, 6, 8, 10)
        val allEven = numbers.all { it % 2 == 0 }
        return allEven
    }

none

是否没有元素满足条件

kotlin 复制代码
/**
     * none:是否没有元素满足条件
     */
    fun noneDemo(): Boolean {
        val numbers = listOf(1, 2, 3, 4, 5)
        val noEven = numbers.none { it % 2 == 0 }
        return noEven
    }

count

统计满足条件的元素个数

kotlin 复制代码
/**
     * count:统计满足条件的元素个数
     */
    fun countDemo(): Int {
        val numbers = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
        val evenCount = numbers.count { it % 2 == 0 }
        return evenCount
    }

firstOrNull

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

kotlin 复制代码
/** firstOrNull:查找第一个满足条件的元素,找不到返回 null */
    fun findDemo(): Int? {
        val numbers = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
        val sameAsFirstOrNull = numbers.firstOrNull { it % 2 == 0 }
        return sameAsFirstOrNull
    }

内联函数 inline(核心重点)

Lambda 的本质问题

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

kotlin 复制代码
// 普通高阶函数
fun operateOnNumber(x: Int, operation: (Int) -> Int): Int {
    return operation(x)
}

编译后近似等价于:

kotlin 复制代码
val lambda = object : Function1<Int, Int> {
    override fun invoke(x: Int): Int = x * 2
}
val result = operateOnNumber(5, lambda)  // 每次调用都创建对象

inline 解决方案

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

kotlin 复制代码
inline fun operateOnNumber1(x: Int, operation: (Int) -> Int): Int {
    return operation(x)
}

fun inlineDemo() {
    val result = operateOnNumber1(5) { it * 2 }
    // 编译后代码会被内联为:val result = 5 * 2
}

inline 的两大好处

消除 Lambda 对象创建 --- 减少内存分配和 GC 压力

支持非局部返回 --- 可以在 Lambda 中直接 return 外层函数

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

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

相关推荐
c2385615 小时前
MySrting的模拟实现
开发语言·c++·算法
三少爷的鞋15 小时前
Android 离线优先架构实践:网络只是本地数据库的同步触发器
android
Rabitebla15 小时前
C++ 继承详解(下):默认成员函数、虚继承底层与设计取舍
c语言·开发语言·数据结构·c++·算法·leetcode
枫叶丹415 小时前
【HarmonyOS 6.0】Live View Kit深度解析:实况胶囊尾部图标的设计哲学与实现全流程
开发语言·华为·harmonyos
吃好睡好便好21 小时前
提取矩阵某一行或某一列元素
开发语言·人工智能·线性代数·算法·matlab·矩阵
巴博尔1 天前
UNIAPP中NVUE页面 动画
android·前端·javascript·ios·uni-app
deepin_sir1 天前
10 - 函数
开发语言·python
z落落1 天前
C#String字符串
开发语言·c#·php
猫头虎-前端技术1 天前
JS 作用域与闭包:从变量提升到闭包陷阱的超详细解析
开发语言·javascript·云计算·bootstrap·ecmascript·openstack·perl