博客
关于我
Java 8 中的 Lambda 表达式 vs. Kotlin 中的 Lambda
阅读量:290 次
发布时间:2019-03-01

本文共 2649 字,大约阅读时间需要 8 分钟。

Kotlin 函数式编程实例与高阶函数

代码示例

package com.easykotlin.lec02fun
fun sum1(x: Int, y: Int): Int {
return x + y
}
fun sum2(x: Int, y: Int) = x + y
// sum2 函数字面量:匿名函数
val sum3 = fun(x: Int, y: Int) = x + y
val s3 = (fun(x: Int, y: Int) = x + y)(1, 1)
val s32 = (fun(x: Int, y: Int) = x + y).invoke(1, 1)
// Lambda
val sum4 = { x: Int, y: Int -> x + y }
val s4 = { x: Int, y: Int -> x + y }(1, 1)
val s42 = { x: Int, y: Int -> x + y }.invoke(1, 1)
val sum5: (Int, Int) -> Int = { x, y -> x + y }
// 高阶函数
fun repeat(n: Int, body: () -> Unit) {
for (i in 1..n) {
body()
}
}
// 类型别名
typealias A = (String) -> Int
typealias B = (Int) -> Boolean
typealias C = (String) -> Boolean
val length: A = { x -> x.length }
val isOdd: B = { x -> x % 2 == 1 }
// 高阶函数(复合函数)
val filterOdd: C = { x -> isOdd(length(x)) }
fun main(args: Array
) {
val list = listOf("a", "abc", "abcbdf", "adsfeeff", "qwedddsssssdd")
// 过滤出 list 中字符串长度是奇数的元素
val result = list.filter(filterOdd)
println(result)
repeat(3) { println("A") }
// 1 + 2 + ... + 100
var sum = 0
var i = 1
repeat(100) {
sum += i
i++
}
println("sum = $sum")
sum1(1, 1)
sum2(1, 1)
sum3(1, 1)
sum4(1, 1)
sum5(1, 1)
println("s3 = $s3")
println("s32 = $s32")
println("s4 = $s4")
println("s42 = $s42")
}

Java 8 对比

public void filter(Filter f, List
integerList) {
for (Integer i : integerList) {
if (f.test(i)) {
System.out.println(i);
}
}
}
// 定义一个 SAM
interface Filter {
boolean test(int x);
}
public void lambdaDemo() {
filter((x) -> x % 2 == 1, Arrays.asList(1, 2, 3, 4, 5, 6, 7));
}

Kotlin 优势

在 Kotlin 中,函数 f: (Int) -> Boolean 也是一种类型,可以像普通的参数变量一样,在函数入参中传递,当然也可以返回一个函数。

高阶函数示例

fun repeat(times: Int, body: () -> Unit) {
for (i in 0 until times) {
body()
}
}
fun main(args: Array
) {
repeat(3, { println("A") })
repeat(3) { println("B") }
var sum = 0
var i = 1
repeat(100) {
sum += i
i++
}
println(sum)
}

Function 接口

Function 接口类型只有一个调用方法:invoke()。

它包含三个动作:传入参数、处理参数、返回结果。

Kotlin 定义了 kotlin.jvm.functions 包里的接口,用于抽象所有函数类型。这些接口包括:

  • Function0:没有参数
  • Function1:有一个参数
  • Function2:有两个参数
  • ...
  • FunctionN:支持 23 个及以上参数

每个接口都继承自 Function,并定义了 invoke() 方法,通过重载括号操作符来传入参数和获取返回值。

匿名函数与 Lambda

val sum: (Int, Int) -> Int = fun(a: Int, b: Int) = a + b
// 或者省略类型声明
val sum = fun(a: Int, b: Int) = a + b
// Lambda 表达式
val sum = { a: Int, b: Int -> a + b }

这些函数对象会被编译为 Function2 类型的实现,可以通过 invoke() 方法调用,也可以直接使用括号操作符:

println(sum.invoke(1, 2))
// 或者
println(sum(1, 2))

小结

相比之下,Kotlin 对函数式编程的支持更加自然优雅。

转载地址:http://biea.baihongyu.com/

你可能感兴趣的文章
Node-RED中连接Mysql数据库并实现增删改查的操作
查看>>
Node-RED中通过node-red-ui-webcam节点实现访问摄像头并截取照片预览
查看>>
Node-RED中配置周期性执行、指定时间阶段执行、指定时间执行事件
查看>>
Node-RED安装图形化节点dashboard实现订阅mqtt主题并在仪表盘中显示温度
查看>>
Node-RED怎样导出导入流程为json文件
查看>>
Node-RED订阅MQTT主题并调试数据
查看>>
Node-RED通过npm安装的方式对应卸载
查看>>
node-request模块
查看>>
node-static 任意文件读取漏洞复现(CVE-2023-26111)
查看>>
Node.js 8 中的 util.promisify的详解
查看>>
node.js debug在webstrom工具
查看>>
Node.js RESTful API如何使用?
查看>>
node.js url模块
查看>>
Node.js Web 模块的各种用法和常见场景
查看>>
Node.js 之 log4js 完全讲解
查看>>
Node.js 函数是什么样的?
查看>>
Node.js 函数计算如何突破启动瓶颈,优化启动速度
查看>>
Node.js 切近实战(七) 之Excel在线(文件&文件组)
查看>>
node.js 初体验
查看>>
Node.js 历史
查看>>