• kotlin函数api


    Kotlin学习(4)Lambda

    记住Lambda的本质,还是一个对象。和JS,Python等不同的是,Kotlin里的Lambda不是方法,而是一个简化了的对象。

    此外,Kotlin里面的没有匿名函数这一说,函数也不是传统的对象。

    看看Kotlin的Lambda

    //Java
    button.setOnClickListener(v -> {//...})
    
    //Kotlin
    button.setOnClickListen{//...}

    一个Lambda函数

    it是一个lamdba隐含对象,可能是Iterable的简写吧

    data class Person(val name: String, val age: Int)
    
    fun main(vararg args: String){
        val people = listOf<Person>(
            Person("Alice",29),
            Person("Bob",31)
        )
    
        //使用隐含对象
        println(people.maxBy { it.age })
        //使用成员对象引用
        println(people.maxBy(Person::age))
        //类Java
        println(people.maxBy{ p: Person -> p.age})
    }
    

    Lambda句法

    //Java
    static IntBinaryOperator add = (x, y) -> x + y;
    
    public static void main(String...args){
        add.applyAsInt(1,2)
    }
    
    
    //Kotlin
    val sum = { x: Int, y: Int -> x + y }
    
    fun main(vararg args: String){
        sum(1,2)
    }

    咋一看挺迷惑的,需要看看Java中的写法

    因为上面说了Lambda是个对象,那么对象能像函数一样调用呐?

    这里写图片描述

    证实了我们的观点,确实是个对象,sum()应该是sum.invoke()的语法糖吧

    直接调用Lambda

    { x: Int, y: Int -> x + y }(1,2)
    
    //run适用于无参数的Lambda
    run { print(24)}

    看一个例子

    transform申明要一个Lambda参数

    public fun <T> Iterable<T>.joinToString(
        separator: CharSequence = ", ", 
        prefix: CharSequence = "", 
        postfix: CharSequence = "", 
        limit: Int = -1, 
        truncated: CharSequence = "...", 
        transform: ((T) -> CharSequence)? = null): String {
        return ...
    }

    在Lambda中使用可变变量

    在Java中,Lambda中不能使用变量,如下

    public static void main(String...args){
        int i = 0;
        Runnable r = () -> {
           i++;//会报错
        };
    }
    
    //只能这么做
    static class I{
        public static int i = 0;
    }
    public static void main(String...args){
        Runnable r = () -> {
            I.i++;
        };
    }

    但是在Kotlin中可以

    var count = 0
    val inc = { count++ }
    • 1
    • 2

    成员引用

    可以视为Java反射包中的Field和Method

    data class Person(val name: String, val age: Int)
    Person::age//property age
    
    fun sulate() = println("aaa")
    val a = run(::salute)//function add
    
    //构造器引用
    val createPerson = ::Person
    val p = createPerson("Alice", 29)
    
    val personAgeFunction = Person::age
    println(personAgeFunction(p)) //29
    
    val thisPersonAgeFunction = p::age
    println(thisPersonAgeFunction()) //29

    最后两个例子可能有些疑惑,但本质personAgeFunction还是一个对象,像函数一样调用还是一个语法糖(personAgeFunction.get())


    函数式API

    典型的声明式编程,和SQL语句有共同之处。语义很好理解,不解释了

    • filter
    • map: map是将集合中的每个元素变成另一种A->B
    • filterKeys
    • mapKeys
    • filterValues
    • mapValues
    • all
    • any
    • count
    • find
    • groupBy
        val people = listOf<Person>(
                Person("a",19),
                Person("b",28),
                Person("c",19),
                Person("d",20)
        )
    
        val result = people.groupBy { it.age }
        println(result)
        println(result.javaClass)
        /*
        {19=[Person(name=a, age=19), Person(name=c, age=19)], 
        28=[Person(name=b, age=28)], 
        20=[Person(name=d, age=20)]}
    
        class java.util.LinkedHashMap
        */
    • flatMap: flatMap将每个元素变成一个集合再合并这些集合A->[1,2…]
    • flatten
    • toList()
    • toSet()
    • asSequence: 类似于Java8的stream()
    //传统链式调用,会产生一个map的结果和一个filter的List结果
    //当集合很大时,有很大的性能开销
    val result = people.map { it.age }
                       .filter { it > 20 }
    
    //改为使用asSequence(),最后别忘了加上toList()
    val result = people.asSequence()
                        .map { it.age }
                        .filter { it > 20 }
                        .toList()

    这里写图片描述

    创建Sequence

    val number = generateSequence(0) { it + 1 }
    val numbersTo100 = number.takeWhile { it <= 100 }
    println(numbersTo100.sum())



    使用map函数对集合进行操作

    fun main(args: Array<String>) {
    val list:Array<Int> = arrayOf(1,2,3,4,5,6,7,8)

    val newList = list.map {
    it*5+10
    }

    val doubleList = list.map(Int::toDouble)

    newList.forEach(::println)
    doubleList.forEach(::println)
    }
    使用flatMap对集合数据进行合并成一个集合

    fun main(args: Array<String>) {
    val list = arrayOf(
    1..10,
    20..30,
    50..100
    )

    val mergeList = list.flatMap {
    it.map {
    "No.$it"
    }
    }

    mergeList.forEach(::println)
    }
    使用reduce对集合进行计算操作

    fun main(args: Array<String>) {
    val list = arrayOf(
    1..10,
    20..30,
    50..100
    )

    val mergeList = list.flatMap { it }
    mergeList.forEach(::println)
    println("总和:${mergeList.reduce(Int::plus)}")
    println("总和:${mergeList.reduce { acc, i -> acc + i }}")

    /**
    * 方式1
    */
    (0..6).map {
    factorial(it)
    }.forEach(::println)

    /**
    * 方式2
    */
    (0..6).map(::factorial).forEach(::println)

    }

    /**
    * 求阶乘
    */
    fun factorial(int: Int): Int {
    if (int == 0) return 1
    return (1..int).reduce { acc, i -> acc * i }
    }
    使用fold对集合进行自定义计算

    fun main(args: Array<String>) {
    /**
    * 对集合进行转化和拼接
    */
    val _str: String = (0..10).joinToString(",")
    println(_str)

    /**
    * 添加一个初始值
    * 打印结果=》9
    */
    println((0..1).fold(8) { acc, i ->
    acc + i
    })

    /**
    * 添加一个StringBuilder的初始值与集合中的元素进行计算操作
    */
    val _str1 = (0..5).fold(StringBuilder()) { acc, i ->
    acc.append(i).append(",")
    }
    println(_str1)

    }

    ---------------------

     
  • 相关阅读:
    iOS书写高质量代码之耦合的处理
    下载历史版本App超详细教程
    iOS-申请邓白氏编码的超详细流程介绍
    AFNetworking之于https认证
    iOS时间问题
    AFNetworking到底做了什么?(二)
    AFNetworking到底做了什么
    iOS7中的ViewController切换
    iOS 视图控制器转场详解
    关于如何写UI及屏幕适配的一些技巧
  • 原文地址:https://www.cnblogs.com/vana/p/10201276.html
Copyright © 2020-2023  润新知