Kotlin 中 Lambda的使用 一、入门 集合的函数式API中Lambda表达式的使用

        很多高级编程语言很早就支持Lambda编程,java从JDK1.8开始支持Lambda编程语法,而kotlin从第一版开始就支持Lambda编程。本章从集合的函数式API的使用做的Kotlin中Lambda入门。

一、Lambda表达式语法

        lambda表达式完整语法:val sum: (Int, Int) -> Int = {x: Int, y: Int -> x + y} 即:{参数名1:参数类型,参数名2: 参数类型 -> 函数体}。其中参数的个数可以是0个也可以是多个。

        lambda表示是整体是在花括号中,参数和函数体用 -> 分割开,在Lambda是类型是可以自动推导的,所有上述表示也可以写成 val sum = {x: Int, y: Int -> x + y}  或 val sum: (Int, Int) -> Int = {x, y -> x + y} 。

        其中 (Int, Int) -> Int 是函数类型,表示是参数为2个Int值,返回值是Int的函数类型,参数和返回值用 -> 分隔开,参数个数也可以0个或者多个。返回值为空Unit不可以省略,Lambda表达式不能指定返回值类型,且最后一行自动最为其返回值。关于函数类型相关知识后边会详细讲到。

二、Lambda表达式在集合函数式API的使用

data class Person(val age: Int, val name: String)
val persons = listOf(Person(16, "一诺"), Person(18, "紫萱"))

        先看一个需求从persons中找出年龄最大的person。按照我们之前的未使用Lambda表达式之前的写法很可能会是如下代码:

fun getMaxAgePerson(): Person {
        var maxAgePerson: Person = persons[0]
        for (person in persons) {
            if (person.age > maxAgePerson.age) {
                maxAgePerson = person
            }
        }
        return maxAgePerson
    }

但如果我们使用集合的函数式API结合Lambda就可以很简单的写成如下方式:

maxAgePerson = persons.maxBy { it.age }

{it.age} 是Lambda的简化写法,下面我们一步步看下它的推导过程。

三、Lambda简化用法的推导演化

        首先查看 maxby 函数的定义:

public inline fun <T, R : Comparable<R>> Iterable<T>.maxBy(selector: (T) -> R): T? {
    //....
}

        可以看出 maxby 是一个Iterable<T> 的扩展函数,接收一个函数类型(参数是泛型T,返回值为实现Comparable的类型R)的参数,同时也是内联函数。

        第一步:所以我们我们第一步声明一个此函数类型的Lambda表达式(不仅lambda表达式还有匿名函数、函数引用...也可以作为函数值)传递给maxby。

val lambda: (Person) -> Int = { person: Person -> person.age }
//根据Lambda的类型推导特性,可以写成val lambda = { person: Person -> person.age }
maxAgePerson = persons.maxBy(lambda)

lambda作为参数传递给maxby。

        第二步:我们直接把Lambda表达式传递到maxby中。

maxAgePerson = persons.maxBy({ person: Person -> person.age })

        第三步:在kotlin中Lambda表达式作为函数最后一个参数时可以将Lambda表达式移到函数括号的外边(匿名函数则不可以),可以写成:

maxAgePerson = persons.maxBy(){ person: Person -> person.age }

        第四步:在kotlin中Lambda表达式是函数的唯一参数参数时,可以将()省略,即:

maxAgePerson = persons.maxBy{ person: Person -> person.age }

        第五步:从maxby的定义可以看出参数的函数类型中参数也是Iterable的泛型T,因此根据Kotlin的类型推导机制,可以不声明参数类型,因此代码可以进一步写为:

maxAgePerson = persons.maxBy{ person -> person.age }

        第六步:当Lambda表达式中只有一个参数时,可以不必声明参数名而是用 it 代替,也因此可以写成:

maxAgePerson = persons.maxBy{ it.age }

以上是maxby函数的简化推导演化的过程。

四、常用的集合的函数式API

(1) filter 过滤集合中的数据,筛选出persons中年龄大于等于18的person:

val newPersons = persons.filter { it.age >= 18 }

(2)minby 和 maxby用法一样筛选出集合中满足条件的最小的元素,筛选中persons中年龄最小的person:

val minAgePerson = persons.minBy { it.age}

(3)map 将集合中的元素映射成另外的值,将persons中的person年龄加一岁:

val newPersons = persons.map { it.age + 1 }

(4)any 集合中是否至少有一个满足条件的元素,persons中是否含有年龄大于等于18的person:

val isAnyPerson = persons.any { it.age >= 18 }

(5)all 和 any的用法一样指是否集合中的元素是否全部满足某个条件,persons中的person是否年龄全部大于等于18:

val isAllPerson = persons.all { it.age >= 18 }

Kotlin 中 Lambda的使用​​​​​​​ 

一、入门Lambda表达式在集合函数式API的使用

二、函数类型和实例化

三、SAM转换 (Single Abstract Method Conversions)

四、内联函数 inline​​​​​​​

猜你喜欢

转载自blog.csdn.net/old_land/article/details/119302252