kotlin--函数式编程

2021-12-06 17:20:00 浏览数 (1)

函数式编程范式主要依赖于高阶函数(以函数为参数或返回值)返回的数据,这些高阶函数专用于处理各种集合,可以联合使用多个同类函数构建链式操作以创建复杂的计算行为。kotlin支持多种编程范式,所以可以灵活运用面向对象编程和函数式编程来解决问题
一、变换

变换是函数式编程中的第一大类函数,变换函数会遍历集合内容,以一个值参传入的变换器函数,变换每个元素,返回包含已修改元素的集合给链上的其他函数

1.map

map变换函数会遍历接收者集合,让变换器函数作用于集合里的每个元素,返回修改后的集合,会作为链上下个函数的输入

代码语言:javascript复制
fun main() {
    val list = listOf("jack", "rose", "danny")
    val mapList = list.map {
        //将集合中每个元素首字母大写
        it.capitalize()
    }.map {
        //将集合中每个元素加上i'm
        "i'm $it"
    }.apply(::println)//打印输出
}

结果: [i'm Jack, i'm Rose, i'm Danny]

原始集合并不会被修改,返回的是一个新的集合,函数式编程的设计理念就是不可变数据的副本在链上的函数间传递

map函数返回的集合大小和原集合一样,但类型不必相同

代码语言:javascript复制
fun main() {
    val list = listOf("jack", "rose", "danny")
    val mapList = list.map {
        //将集合中每个元素首字母大写
        it.capitalize()
    }.map {
        //将集合中每个元素加上i'm后,计算字符串大小
        "i'm $it".length
    }.apply(::println)//打印输出
}

结果: [8, 8, 9]

2.flatMap

flatMap操作一个集合的集合,将多个集合合并成一个集合

代码语言:javascript复制
fun main() {
    val list = listOf("jack", "rose", "danny")
    val list2 = listOf("jack1", "rose2", "danny3")
    val bigList = listOf(list, list2)

    val flat = bigList.flatMap {
        it
    }.apply(::println)
}

结果: [jack, rose, danny, jack1, rose2, danny3]

二、过滤

过滤是函数式编程中的第二大类函数,过滤函数接受一个predicate函数,用它按给定条件检查接收者集合中的每一个元素,并给出true或fasle,为true添加到新集合中

1.filter
代码语言:javascript复制
fun main() {
    val list = listOf("jack", "rose", "danny")
    val filter = list.filter {
        //过滤含有j的字符串
        !it.contains("j")
    }.apply(::println)
}

结果: [rose, danny]

组合使用,实现找素数

代码语言:javascript复制
fun main() {
    val list = listOf(7, 4, 8, 4, 3, 22, 18, 11)
    //找素数
    list.filter {number ->//过滤不是素数的元素 
        (2 until number).map {//遍历2到当前元素值 
            number % it //当前元素取余
        }.none{it == 0}//为0则false
    }.apply (::println)
}

结果: [7, 3, 11]

三、合并

合并是函数式编程中的第三大类函数,合并函数能将不同的集合合并成一个新集合,这和接收者是包含集合的集合的flatMap函数不同

1.zip

zip函数用来合并两个集合,返回一个包含键值对的新集合

代码语言:javascript复制
fun main() {
    val list = listOf("jack", "rose", "danny")
    val list2 = listOf(14, 18, 23)

    list.zip(list2).apply(::println)
}

结果: [(jack, 14), (rose, 18), (danny, 23)]

2.fold

fold函数用来合并值,这个函数接收一个初始累加器值,然后根据匿名函数的结果更新

代码语言:javascript复制
fun main() {
    val list = listOf(14, 18, 23)
    list.fold(0) { acc, value ->
        acc   value
    }.apply(::println)
}

结果: 55

四、为什么要使用函数式编程
五、序列

kotlin还有另外一类集合:惰性集合,类似于类的惰性初始化,惰性集合类型的性能表现优异,尤其是用于包含大量元素的集合时,因为集合元素是按需产生的 kotlin有个内置惰性集合类型叫序列,序列不会索引排序它的内容,也不记录元素个数,在使用一个序列时,它的元素可能有无限多,因为某个数据源能产生无限个元素

1.generateSequence

当你不知道要检查多少个元素才能得到想要的个数个元素时,可以使用generateSequence,如:获取从0开始的1000个素数

代码语言:javascript复制
fun isPrime(number: Int): Boolean {
    //过滤不是素数的元素 
    return (2 until number).map {
        //遍历2到当前元素值 
        number % it //当前元素取余
    }.none { it == 0 }//为0则false
}

fun main() {
    //从3开始
    val squence = generateSequence(3) { value ->
        //每次加1
        value   1
    }.filter {
        isPrime(it)
    }.take(1000)

    println(squence.toList().size)
}

0 人点赞