阅读 73

Kotlin Lambda编程

Lambda编程

集合的创建与遍历

使用内置的listOf()函数初始化集合,使用for-in循环来遍历集合。

val list = listOf("apple", "banana", "orange", "pear", "grape")
for (fruit in list) {
    println(fruit)
}复制代码

listOf()函数创建的是一个不可变的集合,只能用于读取,无法进行添加、修改或删除操作

List集合

使用listOf()函数初始化不可变集合;

使用mutableListOf()函数创建一个可变集合;

val list1 = listOf("apple", "banana", "orange", "pear")
for (fruit in list1) println(fruit)

val list2 = mutableListOf("apple", "banana", "orange", "pear")
list2.add("watermelon")
for (fruit in list2) println(fruit)复制代码

Set集合

Set集合的用法与List集合几乎一模一样,只是将创建集合的方式换成了setOf()mutableSetOf()函数而已。

val set = setOf("apple", "banana", "orange", "pear")
for(fruit in set) println(fruit)复制代码

需要注意,Set集合底层使用hash映射机制来存放数据的,因此集合中的元素无法保证有序,这是和List集合最大的不同之处。

Map集合

Map是一种键值对形式的数据结构,因此在用法上和ListSet集合有较大的不同。

传统的Map用法是先创建一个HashMap的实例,然后将一个个键值对数据添加到Map中:

传统写法:
val map = HashMap<String, Int>()
map.put("apple", 1)
map.put("banana", 2)
map.put("orange", 3)
map.put("pear", 3)复制代码

但在Kotlin中不建议使用put()get()方法来对Map进行添加和读取数据操作,而是更加推荐一种类似于数组下标的语法结构:

推荐写法:
val map = HashMap<String, Int>()
map["Apple"] = 1
map["banana"] = 2
map["orange"] = 3
map["pear"] = 4复制代码

Kotlin中也提供了mapOf()mutableMapOf()函数简化Map的用法

简便写法:
val map = mapOf("apple" to 1, "banana" to 2, "orange" to 3, "pear" to 4)
for ((fruit, number) in map) println("fruit is " + fruit + ",number is " + number)复制代码

to是一个infix函数,使用for-in循环遍历map

函数式API语法结构

如何在一个水果集合里找到单词最长的那个水果?

普通写法:
val list = listOf("apple", "banana", "orange", "pear")
var maxLengthFruit = ""
for (fruit in list) {
    if (fruit.length > maxLengthFruit.length) {
        maxLengthFruit = fruit
    }
}
println("max length fruit is " + maxLengthFruit)

函数式API写法:
val list = listOf("apple", "banana", "orange", "pear")
val maxLengthFruit = list.maxBy { it.length }
println("max length fruit is " + maxLengthFruit)复制代码

Lambda定义:Lambda就是一小段可以作为参数传递的代码

通常情况下,我们向函数传参时只能传入变量,而借助Lambda却允许传入一小段代码

语法结构:{参数名1:参数类型, 参数名2:参数类型 -> 函数体}

首先最外层是一对大括号,如果有参数传入到Lambda表达式中的话,需要声明参数列表,参数列表的结尾使用一个->符号,表示参数列表的结束以及函数体的开始,函数体中可以编写任意行代码,并且最后一行代码会自动作为Lambda表达式的返回值。

maxBy()函数:接受一个Lambda类型参数(Lambda表达式),并且会在遍历集合时将每次遍历的值作为参数传递给Lambda表达式。maxBy()函数的工作原理是根据我们传入的条件遍历集合,从而找到该条件下的最大值。

  1. 接收Lambda表达式作为参数

val list = listOf("apple", "banana", "orange", "pear")
val newList = list.map({fruit: String -> fruit.toUpperCase()})
for(fruit in newList) println(fruit)复制代码
  1. 如果Lambda参数是函数最后一个参数时,可以把Lambda表达式移到函数括号外面

val newList = list.map(){fruit: String -> fruit.toUpperCase()}复制代码
  1. 如果Lambda参数是函数唯一一个参数时,可以省略函数的括号

val newList = list.map{fruit: String -> fruit.toUpperCase()}复制代码
  1. 基于类型推导机制,Lambda表达式中的次数列表在大多数情况下不必声明参数类型

val newList = list.map{fruit -> fruit.toUpperCase()}复制代码
  1. Lambda表达式的参数列表只有一个参数时,不必声明参数名,使用it关键字代替

val newList = list.map{it.toUpperCase()}复制代码

常用API

  • map:用于将集合中的每个元素都映射成一个另外的值,映射的规则在Lambda表达式中指定,最终生成一个新的集合

  • filter:用来过滤集合中的数据,可以配合map使用(会保留符合条件的)

  • any:用来判断集合中是否至少存在一个元素满足指定条件

  • all:用来判断集合中是否所有元素都满足指定条件

保留5个字母以内的,再转大写(先过滤再操作)
val newList = list.filter { it.length <= 5 }
        .map { it.toUpperCase() }

any函数表示集合中是否有5个字母以内的单词
all函数表示集合中是否所有单词都在5个单词以内
val anyResult = list.any { it.length <= 5 }
val allResult = list.all { it.length <= 5 }
println("anyResult is " + anyResult + ", allResult is " + allResult)
输出结果:
anyResult is true, allResult is false复制代码

java函数式API

如果在Kotlin代码中调用了一个java方法,并且该方法接收一个java单抽象方法接口参数,就可以使用函数时APIjava单抽象方法接口指的是接口中只有一个待实现方法,如果接口中有多个待实现方法,则无法使用函数式API。前提:Kotlin中调用java方法,并且单抽象方法接口也必须式萤java语言定义的。

Runnable接口是一个最为常见的单抽象方法接口,这个接口中只有一个待实现的run()方法。

java写法:
new Thread(new Runnable(){
    @Override
    public void run() {
        System.out.println("Thread is running");
    }
}).start();复制代码
Kotlin写法:舍弃new关键字,创建匿名类实例的时候改用object关键字
Thread(object: Runnable{
    override fun run() {
        println("Thread is running")
    }
}).start()

简化:1.因为Runnable类中只有一个待实现方法,不需要显式重写run()方法
Thread(Runnable {
    println("Thread is running")
}).start()

再简化:2.如果一个Java方法的参数列表中不存在一个以上Java单抽象接口方法,可以将接口名省略
Thread({
    println("Thread is running")
}).start()

最简化:3.当Lambda表达式时方法的最后一个参数时,可以将表达式要到方法括号的外。同时,如果Lambda表达式还是方法的唯一一个函数,还可以把方法的括号省略
Thread{
    println("Thread is running")
}.start()


作者:iuoip
链接:https://juejin.cn/post/7019976944800235551


文章分类
后端
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐