(二十三)Kotlin简单易学 基础语法-什么是函数式编程
什么是函数式编程
我们一直在学习面向对象编程范式,另一个较知名的编程范式是诞生于20世纪50年代,基于抽象数学的λ演算发展而来的函数编程,尽管函数式编程语言更常用在学术而非商业软件领域,但它的一些原则适用于任何编程语言,函数式编程范式主要依赖于高阶函数(以函数为参数或返回函数)返回的数据,这些高阶函数专用于处理各种集合,可方便地联合多个同类函数构建链式操作以创建复杂地计算行为,Kotlin支持多种编程范式,所以你可以混用面向对象编程和函数式编程范式来解决手头的问题。
函数类别
一个函数式应用通常由三大类函数构成:变换transform,过滤filter,合并combine。每类函数都针对集合数据类型设计,目标是产生一个最终结果。函数式编程用到的函数生来都是可组合的,也就是说,你可以组合多个简单函数来构建复杂的计算行为。
变换函数
变换是函数式编程的第一大类函数,变换函数会遍历集合内容,用一个以值参形式传入的变换器函数,变换每一个元素,然后返回包含已修改元素的集合给链上的其他函数。 最常用的两个函数Map和flatMap
map函数
map变换函数会遍历接收者集合,让变换器函数作用于集合里的各个元素,返回结果是包含已修改元素的集合,会作为链上下一个函数的输入。
fun main() {
val animals = listOf("zebra", "rat")
println( animals.map {
"A bay $animals" }
)
}
可以看到,原始集合没有被修改,map变换函数和你定义的变换器函数昨晚事情后,返回的是一个新的集合,这样,变量就不用变来变去。 事实上,函数式编程支持的设计理念就是不可变数据的副本在链上的函数间传递。
map
map返回的集合中的元素个数和输入集合必须一样,不过的新集合里的元素可以是不同类型的。
fun main() {
val animals = listOf("zebra", "rat")
val map = animals.map {
it.length
}
println(map)
}
flatMap
flatMap函数操作一个集合的集合,将其中多个集合中的元素合并返回一个包含所有元素的单一集合。
fun main() {
val flatMap = listOf(listOf(1, 2, 3), listOf(4, 5, 6)).flatMap {
it
}
println(flatMap)
}
过滤函数filter
过滤是函数式编程的第二类函数,过滤函数接受一个predicate函数,用它按给定条件检查接收者集合里的元素并给出true或false的判定。如果predicate函数返回true,受检元素就会添加到过滤函数返回的新集合里。如果predicate函数返回false,那么收检元素就被移出新集合。
过滤集合中元素含有“J”的字母的元素
fun main() {
val list = listOf("Jack", "Tom").filter {
it.contains("J")
}
println(list)
}
filter过滤函数接受一个predicate函数,在flatMap遍历它的输入集合中的所有元素时,fiiter函数会让predicate函数按过滤条件,将符合条件的元素都放入它返回的新集合里。最后,flamap会把变换器函数返回的子集合合并在一个新即合理。
fun main() {
val list = listOf(
listOf("red apple", "green apple", "blue apple"),
listOf("red fish", "blue fish"),
listOf("yellow banana", "teal banana"),
)
println(list.flatMap {
it.filter { it.contains("red") }
})
}
找素数,除了1和它本身,不能被任何数整除的数。仅使用了几个简单函数,我们就解决了找素数这个比较复杂的问题,这就是函数式编程的独特魅力:每个函数做一点,组合起来就能干大事。
fun main() {
val list = listOf(7, 8, 11, 22, 15, 185, 11)
val filter = list.filter { number ->
(2 until number).map {
number % it
}.none { it == 0 }
}
println(filter)
}
合并函数
合并是函数式编程的第三大类函数,合并函数能将不同的集合合并成一个新集合,这和接收者是包含集合的集合的flatMap函数不同,
zip 函数
zip合并函数来合并两个集合,返回一个包含键值对的新集合。
fun main() {
val list1 = listOf("Jack", "Jason")
val list2 = listOf("Yuang","L")
println(list1.zip(list2).toMap())
}
fold函数
另一个可以用来合并值的合并类函数是fold,这个合并函数接受一个初始累加器值,随后会根据匿名函数的结果更新。
fun main() {
println( listOf(1, 2).fold(0) { acc, i ->
acc + (i * 3)
})
}
|