Kotlin学习(4)Lambda

记住Lambda的本质,还是一个对象。和JS,Python等不同的是,Kotlin里的Lambda不是方法,而是一个简化了的对象。

此外,Kotlin里面的没有匿名函数这一说,函数也不是传统的对象。

看看Kotlin的Lambda

//Java
button.setOnClickListener(v -> {//...})

//Kotlin
button.setOnClickListen{//...}

一个Lambda函数

it是一个lamdba隐含对象,可能是Iterable的简写吧
data class Person(val name: String, val age: Int)

fun main(vararg args: String){
    val people = listOf<Person>(
        Person("Alice",29),
        Person("Bob",31)
    )

    //使用隐含对象
    println(people.maxBy { it.age })
    //使用成员对象引用
    println(people.maxBy(Person::age))
    //类Java
    println(people.maxBy{ p: Person -> p.age})
}

Lambda句法

//Java
static IntBinaryOperator add = (x, y) -> x + y;

public static void main(String...args){
    add.applyAsInt(1,2)
}


//Kotlin
val sum = { x: Int, y: Int -> x + y }

fun main(vararg args: String){
    sum(1,2)
}
咋一看挺迷惑的,需要看看Java中的写法
因为上面说了Lambda是个对象,那么对象能像函数一样调用呐?

这里写图片描述

证实了我们的观点,确实是个对象,sum()应该是sum.invoke()的语法糖吧

直接调用Lambda

{ x: Int, y: Int -> x + y }(1,2)

//run适用于无参数的Lambda
run { print(24)}

看一个例子

transform申明要一个Lambda参数
public fun <T> Iterable<T>.joinToString(
    separator: CharSequence = ", ", 
    prefix: CharSequence = "", 
    postfix: CharSequence = "", 
    limit: Int = -1, 
    truncated: CharSequence = "...", 
    transform: ((T) -> CharSequence)? = null): String {
    return ...
}

在Lambda中使用可变变量

在Java中,Lambda中不能使用变量,如下
public static void main(String...args){
    int i = 0;
    Runnable r = () -> {
       i++;//会报错
    };
}

//只能这么做
static class I{
    public static int i = 0;
}
public static void main(String...args){
    Runnable r = () -> {
        I.i++;
    };
}
但是在Kotlin中可以
var count = 0
val inc = { count++ }

成员引用

可以视为Java反射包中的Field和Method
data class Person(val name: String, val age: Int)
Person::age//property age

fun sulate() = println("aaa")
val a = run(::salute)//function add

//构造器引用
val createPerson = ::Person
val p = createPerson("Alice", 29)

val personAgeFunction = Person::age
println(personAgeFunction(p)) //29

val thisPersonAgeFunction = p::age
println(thisPersonAgeFunction()) //29
最后两个例子可能有些疑惑,但本质personAgeFunction还是一个对象,像函数一样调用还是一个语法糖(personAgeFunction.get())

函数式API

典型的声明式编程,和SQL语句有共同之处。语义很好理解,不解释了
  • filter
  • map: map是将集合中的每个元素变成另一种A->B
  • filterKeys
  • mapKeys
  • filterValues
  • mapValues
  • all
  • any
  • count
  • find
  • groupBy
    val people = listOf<Person>(
            Person("a",19),
            Person("b",28),
            Person("c",19),
            Person("d",20)
    )

    val result = people.groupBy { it.age }
    println(result)
    println(result.javaClass)
    /*
    {19=[Person(name=a, age=19), Person(name=c, age=19)], 
    28=[Person(name=b, age=28)], 
    20=[Person(name=d, age=20)]}

    class java.util.LinkedHashMap
    */
  • flatMap: flatMap将每个元素变成一个集合再合并这些集合A->[1,2…]
  • flatten
  • toList()
  • toSet()
  • asSequence: 类似于Java8的stream()
//传统链式调用,会产生一个map的结果和一个filter的List结果
//当集合很大时,有很大的性能开销
val result = people.map { it.age }
                   .filter { it > 20 }

//改为使用asSequence(),最后别忘了加上toList()
val result = people.asSequence()
                    .map { it.age }
                    .filter { it > 20 }
                    .toList()

这里写图片描述

创建Sequence

val number = generateSequence(0) { it + 1 }
val numbersTo100 = number.takeWhile { it <= 100 }
println(numbersTo100.sum())
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值