美文网首页
Kotlin中函数式编程API(3)✔️三大基础函数

Kotlin中函数式编程API(3)✔️三大基础函数

作者: 狼性代码人 | 来源:发表于2019-06-13 16:01 被阅读0次
    • filter
    • map
    • reduce

      过滤映射聚合 是数据的三大基本操作,围绕这三大基础操作会有很多函数,但其中有三个函数是作为基础的函数:filtermapreduce

    一、filter

      过滤操作使用filter函数,它可以对Collection集合、Map集合 或 数组 元素进行过滤,Collection 集合 和 数组 返回的是一个 List集合Map 集合返回的还是一个 Map 集合。

    class Person(val name: String, val age: Int) {
        override fun toString(): String = "[$name, $age]"
    }
    
    val people = listOf(
        Person("Tony star", 3),
        Person("Lawrence Li", 3), Person("tom Chen", 3),
        Person("Alex", 3), Person("Xiao san", 3)
    )
    
    val peopleMap = mapOf(
        "a" to Person("Tony star", 3),
        "b" to Person("Lawrence Li", 3), "bf" to Person("tom Chen", 3),
        "af" to Person("Alex", 3), "sex" to Person("Xiao san", 3)
    )
    
    fun main(args: Array<String>?) {
        people.filter {
            it.name.startsWith("t", ignoreCase = true)
        }.forEach {
            println("{name=${it.name}, age=${it.age}}")
        }
        peopleMap.filter {
            it.key.startsWith("a") &&
                    it.value.name.startsWith("a", ignoreCase = true)
        }.forEach { println("(${it.key}, ${it.value.toString()})") }
    }
    
    // 输出结果
    
    2019-06-13 15:17:48.706 I: {name=Tony star, age=3}
    2019-06-13 15:17:48.707 I: {name=tom Chen, age=3}
    2019-06-13 15:17:48.710 I: (af, [Alex, 3])
    

      filter函数中的 Lambda 表达式返回布尔值,true的元素进入下一个函数,false的元素被过滤掉,表达式it.name.startsWith("t", ignoreCase = true)是判断集合元素的name属性是否为 t 字母开头,ignoreCase = true忽略大小写进行比较。

    二、map

      映射操作使用 map 函数,它可以对 Collection 集合、Map 集合 或 数组 元素进行变换并 返回一个List 集合。

    fun main(args: Array<String>?) {
        people.map { it.name }.forEach { println(it) }
        peopleMap.map { it.value }.filter { it.name.startsWith("T") }
            .forEach { println(it) }
    }
    
    // 输出结果
    
    2019-06-13 15:38:40.567 I: Tony star
    2019-06-13 15:38:40.567 I: Lawrence Li
    2019-06-13 15:38:40.567 I: tom Chen
    2019-06-13 15:38:40.567 I: Alex
    2019-06-13 15:38:40.567 I: Xiao san
    2019-06-13 15:38:40.573 I: [Tony star, 3]
    

      Map 函数对集合进行变换,it.name 是变换表达式,将计算的结果放到一个新的 List 集合中。

    三、reduce

      聚合操作会将 Collection 集合 或 数组 中的数据聚合起来输出单个数据,聚合操作中最基础的是归纳函数 reducereduce 函数会将 集合数组 的元素按照指定的算法积累叠加起来,最后输出一个数据。

    • 分析 reduce 源码
    // reduce的kotlin源码
    
    public inline fun <S, T : S> Iterable<T>.reduce(operation: (acc: S, T) -> S): S {
        val iterator = this.iterator()
        if (!iterator.hasNext()) throw UnsupportedOperationException("Empty collection can't be reduced.")
        var accumulator: S = iterator.next()
        while (iterator.hasNext()) {
            accumulator = operation(accumulator, iterator.next())
        }
        return accumulator
    }
    

      源码分析:1、从源码看 reduce 是迭代器的 Iterable 的扩展函数。2、从方法体第一行代码 val iterator = this.iterator() 分析凡是对象内含有 iterator() 函数并且返回值为 Iterator<T> 类型都可以调用 reduce 扩展函数。3、函数体内定义了局部变量 accumulator 存放返回值,初始值为迭代器的第一个存储值,当迭代器中存储值大于2个时,调用 operation 表达式运算,注意 operation 第一次调用时参数为 accumulator,即迭代器第一个存储值。

    • reduce 使用案例
    class Student(val name: String, val score: Int) {
        override fun toString(): String = "[$name, $score]"
    }
    
    val students = setOf(
        Student("Tony star", 64), Student("小三", 99),
        Student("Lawrence Li", 78), Student("tom Chen", 86),
        Student("Alex", 25), Student("小五", 95)
    )
    
    fun main(args: Array<String>?) {
        val total = students.map { it.score }.reduce { total, score -> total + score }
        println("total score is $total")
    }
    
    // 输出结果
    
    2019-06-13 15:59:00.153 I: total score is 447
    

      调用 reduce 函数计算分数,其中 total 参数是上次积累的计算结果,score 为当前元素,total + score 表达式是进行累加。

    相关文章

      网友评论

          本文标题:Kotlin中函数式编程API(3)✔️三大基础函数

          本文链接:https://www.haomeiwen.com/subject/hkijfctx.html