集合的函数式API
- Lambda定义
- Lambda表达式的语法结构
- 集合的函数式API—map
- 集合的函数式API—filter
- 集合的函数式API—any与all
API即
Application Programming Interface
,应用程序接口。
函数式API
有很多,这里重点学习
函数式API
的语法结构,也是
Lambda表达式
的函数结构。
首先我们像一个问题:如何在一个水果集合里找到单词最长的水果?
当然我们想到循环整个集合,依次比较长度,找到最长的那个,代码如下:
fun main(){val fruit = listOf(\"苹果\", \"香蕉\", \"橘子\", \"桃\", \"葡萄\", \"火龙果\")var maxFruit = \"\"for (eachOne in fruit){if (eachOne.length > maxFruit.length){maxFruit = eachOne}}println(\"名字最长的水果是“$maxFruit”\")}
当然这样的写法已经相当不错了,但如果我们使用使用
集合
的
函数式API
,会很简单:
fun main(){val fruit = listOf(\"苹果\", \"香蕉\", \"橘子\", \"桃\", \"葡萄\", \"火龙果\")val maxFruit = fruit.maxBy{ it.length }println(\"名字最长的水果是“$maxFruit”\")}
相当简洁,你可能看得比较吃力,等你学完
Lambda编程
,你就会觉得简单很多了。
Lambda定义
直白地说:
Lambda
就是一小段可以作为参数传递的代码。
从定义上看,我们普通函数只能传入参数,
Lambda
却允许传入一小段代码,当然
Lamdba
并没有对传入代码长度进行限制,可为了代码可读性,通常不建议传入过长代码。
Lambda表达式的语法结构
{参数名1: 参数类型, 参数名2: 参数类型 -> 函数体}
这是
Lambda
最完整的语法结构定义。
- 最外层是一对
大括号
- 参数传入
Lambda表达式
,需要声明参数列表,
-
->
声明参数列表结束,以及函数体开始
- 函数体可以编写任意代码(不建议过长)
- 最后一行代码自动作为
Lambda表达式
的返回值
当然很多时候我们不需要使用完整语法,但简化版更难理解,因此我们一步步推导演化。
回到刚才的找最长水果名字的代码:
-
maxBy()
函数只是一个普通函数,只不过它接收了一个
Lambda
类型的参数。
-
每次循环遍历的值,作为
Lambda表达式
的参数传入。
-
maxBy()
函数是根据我们的传入,找到该条件下的最大值,此处的条件即为“单词的长度“。
理解工作原理之后,我们用完整的代码完成这一功能:
fun main(){val fruit = listOf(\"苹果\", \"香蕉\", \"橘子\", \"桃\", \"葡萄\", \"火龙果\")val lambda = {Fruits:String -> Fruits.length}val maxFruit = fruit.maxBy(lambda)println(\"名字最长的水果是“$maxFruit”\")}
略有复杂,接下来我们化简代码:
- 我们省略名为
lambda
的变量
val maxFruit = fruit.maxBy({Fruits:String -> Fruits.length})
- Kotlin规定,当
Lambda参数
是函数最后参数时,
Lambda参数
可以在括号外面。
val maxFruit = fruit.maxBy(){Fruits:String -> Fruits.length}
- 当
Lambda参数
是函数唯一参数时,
()
也可省略
val maxFruit = fruit.maxBy{Fruits:String -> Fruits.length}
- 由于Kotlin优秀的类型推导机制,大多时候我们不需要声明参数类型
val maxFruit = fruit.maxBy{Fruits -> Fruits.length}
-
Lambda表达式
只有一个参数时,也不必声明参数名,可以用
it
代替
val maxFruit = fruit.maxBy{ it.length }
这样,我们得到了和开始一摸一样的代码。
集合的函数式API—map
map函数
是很常用的一种
函数式API
,它可以将
集合
中的每个元素都映射成一个另外的值,映射规则在
Lambda表达式
指定,最终生成一个新的
集合
。比如我们要把英文小写变成大写:
fun main(){val fruit = listOf(\"apple\", \"banana\", \"orange\")val newFruit = fruit.map{ it.toUpperCase() }for (eachOne in newFruit){println(\"$eachOne \")}}
当然
map
还可以对
集合
取长度、取首字母等等,只要在
Lambda表达式
中写自己的逻辑即可。
集合的函数式API—filter
顾名思义,此函数用于过滤集合里面的数据。比如我们想找出名字在五个字母以内的水果:
fun main(){val fruit = listOf(\"apple\", \"banana\", \"orange\")val newFruit = fruit.filter{ it.length <= 5 }.map { it.toUpperCase() }for (eachOne in newFruit){println(\"$eachOne \")}}
-
filter
与
map
一起,先进行过滤再映射;比起先映射再过滤,效果相同,但有着更高的效率。
集合的函数式API—any与all
-
any函数
用于判断:集合中是否
至少
有一个元素满足规定条件
-
all函数
用于判断:集合中是否
所有
元素都满足规定条件
我们依然使用
单词长度在5个字母以内
的判断条件,
any
判断是否存在这样的单词,
all
判断单词是否都满足这样的条件。
fun main(){val fruit = listOf(\"apple\", \"banana\", \"orange\")val anyFruit = fruit.any{ it.length <= 5 }val allFruit = fruit.all{ it.length <= 5 }println(\"any的判断结果是:$anyFruit \")println(\"all的判断结果是:$allFruit \")}
这样,我们基本的
Lambda表达式
语法结构和几个常用的
函数式API
学习完啦,虽然还有很多其他的
函数式API
,但只要参考文档,应该不难理解啦。
欢迎关注小试编程