一、基础语法结构
val sum: (Int, Int) -> Int = { a, b -> a + b }
println(sum(3,5)) // 输出 8 :ml-citation{ref="7" data="citationList"}
-
组成要素:
- 参数列表:
(a, b)或省略括号的单参数it - 箭头符号:
->(不可省略) - 函数体:最后一行作为返回值 68
- 参数列表:
-
类型声明方式:
kotlinCopy Code // 完整声明 val greet: (String) -> Unit = { name -> println("Hello $name") } // 类型推断简写 val square = { x: Int -> x * x } :ml-citation{ref="6,7" data="citationList"}
二、与Java函数 对比
//1.函数声明 用Lambda 表达式
val method01 : () -> Unit
//public void method01()
val method02 : (Int,Int) -> Unit
//public void method02(int int1,int int2)
val method03 : (String,Double) -> Any
//public Object method03(String str,Double dou)
var method04 : (Int,Double,Long,String) -> Boolean
//public Boolean method04(int x1,double x2,long x3,String x4)
var method05 : (Int,Int) -> Int
//public int method5(int x1,int x2)
三、案例解析
val method1:()-> Unit = { println("我是method1 函数")}
// val method1 = { println("我是method1 函数")}
method1() //调用函数 ()== 操作符重载,invoke操作符
method1.invoke() //调用函数
// val method2:(Int,Int)->Unit= {x,y -> println("我是method2函数 参数1$x,参数2$y")}
val method2 = {x:Int,y:Int -> println("我是method2函数 参数1$x,参数2$y")}
method2(1,2)
method2.invoke(1,2)
// val method3 : (String,Double) -> Any = {x,y -> "你传递的值分别是 $x 与 $y"}
val method3 = {x:String,y:Double -> "你传递的值分别是 $x 与 $y"}
println(method3.invoke("你好",4.0))
// val method4 : (number1:Int,number2:Int) -> String = {number1,number2 -> number1.toString() + number2.toString()}
val method4 = {number1:Int,number2:Int ->number1.toString() + number2.toString() }
println(method4.invoke(1,2))
// var method5 : (Int,Int) -> Int = {x,y -> x+y}
var method5 = {x:Int,y:Int -> x+y}
println(method5(1,3))
//先声明 后实现
val method6:(Int,Int) -> Int //先声明
method6 = fun(x:Int,y:Int):Int = x + y
println(method6(1,3))
//先声明 后实现 类型推断
val method7:(Int) -> String
method7 = fun(num:Int):String = num.toString()
println(method7(88))
//声明 实现一气呵成
val method8: (Int) -> String/**左边是声明**/ /***右边是实现***/ = {x -> x.toString()}
println(method8(99))
val method9:(String,String) ->Unit = {str1,str2 -> println("传入参数1$str1,传入参数$str2")}
method9.invoke("AA","BB")
//只有一个参数时候,如果你不写,就会默认有一个it替代,会自动添加,两个或多个时就没有
val method10:(String) ->Unit = {
println("只有一个参数 默认it $it")
}
val method11:(Int) ->Unit = {
when(it){
1 -> println("你传递进来的是一")
in 10..20 -> println("你传递进来的是10到20之间的数字")
else -> println("你传递的数字不满")
}
}
method11.invoke(15)
// _ 拒收,可以提高一点性能
val method12:(Int,Int) ->Unit = {_,x -> println("传递的第二个参数是$x")}
method12.invoke(100,101)
//(Any) -> Any
val method13 = {str:Any -> str}
println(method13.invoke(true))
println(method13.invoke(14.556))
//(Char) ->Unit
val method14 = { char:Char ->
if (char.equals('男')) "这是一名男士" else if (char.equals('女')) "这是一名女士"
else "这是未知"
}
println(method14.invoke('男'))
println(method14.invoke('好'))
//(Int) ->Unit
var method15 = {x:Int -> println("你传递的值$x")}
//覆盖了 method15 ,但是还是(Int) ->Unit
method15 = {println("覆盖的也能拿到值:$it")} //这里注意一点是 覆盖的时候前面不能有声明符号了
method15.invoke(55)
// ? 可传null
var method16 = {str1:String?,str2:String -> println("参数$str1,参数2$str2")}
method16.invoke("张飞","赵云")
method16.invoke(null,"赵云")
//需求:你传递什么我打印什么
// (Any) -> Any
val method17 = {x:Any -> println("传递啥输出啥值:$x")}
method17.invoke(111)
method17.invoke(3.1415)
method17.invoke("hello")
val method19:String.() -> Unit = {
println("你是$this")
}
"DDD".method19()
//两数相加结果 这里有主意一点是 ${} Kotlin 中的 ${} 是字符串模板的核心语法,用于在字符串中嵌入变量或表达式
val method20:Int.(Int) -> Unit = {
println("两数相加结果:${this+it}")
}
2.method20(2)
//三数相加结果
val method21:Double.(Double,Double) -> Unit = {
d1,d2 ->
println("3数相加结果:${this +d1 +d2}")
}
4.5.method21(3.0,5.0)
//(Char) -> String
val method22: Char.(String) ->String = {
if (this =='男') "这是一名男士" else if (this =='女') "这是一名女士"
else it
}
println('男'.method22("未知"))
println('A'.method22("未知"))
fun Char.method23(default: String):String{
return if (this =='男') "这是一名男士" else if (this =='女') "这是一名女士"
else "未知"
}
println('男'.method23("未知"))
println('A'.method23("未知"))
四、特殊使用技巧
-
带接收者的 Lambda:
kotlinCopy Code val buildString: StringBuilder.() -> Unit = { append("Hello") append(" World") } val sb = StringBuilder() sb.buildString() println(sb) // 输出 "Hello World" :ml-citation{ref="8" data="citationList"} -
空安全调用:
kotlinCopy Code val nullableStr: String? = null nullableStr?.let { println(it.length) // 安全执行,不会触发 NPE :ml-citation{ref="7" data="citationList"} } -
集合操作链:
kotlinCopy Code val result = (1..10) .filter { it % 3 == 0 } .map { it * 2 } .takeIf { it.size > 2 } ?: emptyList() :ml-citation{ref="7,8" data="citationList"}
五、性能优化要点
| 场景 | 推荐方案 | 说明 |
|---|---|---|
| 频繁调用的 Lambda | 使用 inline 关键字修饰高阶函数 | 避免生成匿名类,减少内存开销 8 |
| 长Lambda链 | 使用序列(asSequence()) | 延迟计算提升性能 |
| 多参数场景 | 使用具名参数 | 提高代码可读性 |
六、与 Java 交互对比
| 特性 | Kotlin Lambda | Java Lambda |
|---|---|---|
| SAM 转换 | 自动支持(适用 Java 接口) | 需要函数式接口注解 |
| 空安全处理 | 支持空安全调用符 ?. | 需要显式 null 检查 |
| 闭包变量修改 | 允许修改非 final 变量 | 只能访问 final/有效 final 变量 |
通过合理使用 Lambda 表达式,可使代码更简洁高效。建议优先在集合操作、回调处理、DSL 构建等场景中使用,但需注意避免过度嵌套导致的代码可读性下降