• Kotlin学习之2


    ===比较引用

    ==比较值

    集合类型

    不可变List:List

    可变List:MutableList

    不可变Map:Map

    可变Map:MutableMap

    不可变Set:Set

    可变Set:MutableSet

    创建集合

    val map:Map=mapOf("name" to "benny","age" to 20)

    val map2:Map=mutableMapOf("name" to "benny","age" to 20)

    val intList:List = listOf(1,2,3)

    val intList2:MutableList = mutableListOf(1,2,3)

    val intList3 = ArrayList()

    只有可变的才能添加、删除元素

    集合遍历

    for(i in 0..10){}

    for(e in list){}

    while{}

    do {

    } while

    list.forEach{

    }

    集合可额外直接通过+-来添加、删除元素

    val stringList = ArrayList()

    stringList += "a"

    stringList -= "a"

    还可以通过[]进行下标索引取值、赋值

    stringList[1]  = "b"

    特殊集合类型:Pair标识一对值、Triple表示一个三值集合

    val pair = "hello" to "Kotlin

    val pair = Pair("Hello", "Kotlin")

    val first = pair.first

    val second = pair.second

    val (x, y) = pair

    val triple = Triple("x" 2, 3.0)

    val first = triple.first

    val second = triple.second

    val third = triple.third

    val (x, y, z) = triple

    数组类型

    整形:IntArray、

    整形装箱:Array

    字符:CharArray

    字符装箱:Array

    字符串:Array

    数组创建

    val a = IntArray(2)

    a.size:数组长度

    a[0]:引用数组值

    遍历与集合一样

    区间类型

    val intRange = 1..10 闭区间,包括起止值

    val intRangeExclusive = 1 until 10 不包括结束值

    倒序区间

    val intRangeReverse = 10 downTo 1 包括起止值

    步长

    val intRangeWithStep = 1..10 step 2

    函数定义

    fun main(args:Array):Unit{

            println(args.contentToString())

    }

    其中函数返回值为Unit可以省略,跟Java void类型一样

    函数引用

    fun foo() {}  val f:()-> Unit= ::foo

    fun foo(p0: Int): String {} val g:(Int)->String = ::foo

    class Foo {

            fun bar(p0: String, p1: Long): Any{

            }

    }

    val h:(Foo, String, Long)->Any = Foo::bar

    其中,等号右侧冒号前面有类名的是类对象的方法引用,在调用时也要传对象实例才行

    val foo = Foo()

    h(foo, "qq", 1)

    变长参数:vararg

    fun multiParameters(vararg ints: Int) {

    }

    函数默认参数

    fun defaultParameter(x: Int, y: Int, z: Long = 0L) {

    }

    如果默认参数不是最后一个,必须使用具体参数名

    fun defaultParamter(x: Int = 5, y: String, z: Long = 0L) {

    }

    defaultParamter(y = "hello")

    高级函数,函数的参数可以是另一个函数

    fun test(p: (Foo, String, Long)-> Any) {

    }

    val x = Foo::bar

    test(x)

    运算符重载

    kotlin支持运算符重载,类似C++,kotlin中的==、+、>、[]、包括函数调用符号()都是kotlin中内置好的重载运算符

    fun main(args: Array) {
        val value = "Hello Kotlin"
        println(value - "Hello")
        println(value * 2)
    
        val star = "*"
        println(star * 20)
        println(value / 3)
        println(value / "l")
        println(value / "ld")
    }
    
    //减
    operator fun String.minus(right: Any?) = this.replaceFirst(right.toString(), "")
    
    //乘
    operator fun String.times(right: Int): String {
        return (1..right).joinToString("") { this }
    }
    
    //除
    operator fun String.div(right: Any): Int {
        val right = right.toString()
        return this.windowed(right.length, 1, transform = {
            it == right
        }).count { it }
    }
    

    重载运算符的定义特点就是类定义扩展方法,方法名和运算符对应的描述,可以通过https://kotlinlang.org/docs/reference/operator-overloading.html#unary-prefix-operators

    进行查询,方法前使用operator关键字修饰

    lambda表达式

    kotlin里的lambda表达式是一个匿名函数的语法糖,因此它的类型其实就是对应的函数类型

    val func: ()->Unit = fun() {

            println("hello")

    }

    val func2 = {p:Int->

            println(p)

            "hello"

    }

    println(func2(1))

    中缀函数,如果函数:是成员函数/扩展函数、只有一个参数、标有infix关键字,就可以认为是一个中缀函数

    class Structure() {
        infix fun createPyramid(rows: Int) {
            var k = 0
            for (i in 1..rows) {
                k = 0
                for (space in 1..rows - i) {
                    print("  ")
                }
                while (k != 2 * i - 1) {
                    print("* ")
                    ++k
                }
                println()
            }
        }
    }
    fun main(args: Array) {
        val p = Structure()
        p createPyramid 4
    }

    其本质还是类的扩展方法,前面加infix关键字,可能是为了实现更加语义化的书写方式

    高阶函数

    高阶函数简单来说就是函数的参数可传递另一个函数,常见于forEach表达式

    val intArray = IntArray(5) { it + 1}

    intArray.forEach {

            println(it)

    }

    intArray.forEach(::println)

    intArray.forEach {

            println("Hello % it")

    }

    例子:定义一个函数打印方法耗时

    fun cost(block: () -> Unit) {
        val start = System.currentTimeMillis();
        block()
        println("${System.currentTimeMillis() - start}ms")
    }
    
    fun fibonacci(): () -> Long {
        var first = 0L
        var second = 1L
        return {
            val next = first + second
            val current = first
            first = second
            second = next
            current
        }
    }
        cost {
            val fibonacciNext = fibonacci()
            for(i in 0..10) {
                println(fibonacciNext())
            }
        }

    内联函数

    添加inline关键字的函数标记为内联函数,内联函数的特点是,代码会被直接插入到调用处,编译的代码反编译的结果就是代码直接插入到调用处的结果。内联函数效率高一些。

    inline fun cost(block: () -> Unit) {
        val start = System.currentTimeMillis();
        block()
        println("${System.currentTimeMillis() - start}ms")
    }
    cost {
        println("Hello")
    }

    编译后等价于

    val start = System.currentTimeMillis();

    block()

    println("${System.currentTimeMillis() - start}ms")

    内联函数的返回

    val ints = intArrayOf(1, 2, 3, 4)

    ints.forEach{

            if(it ==  3) return @forEach

            println("Hello $it")

    }

    这里面的return等价于continue,因为在非循环体内,无法使用continue,所以使用return@方法名可返回该函数的上一层。

  • 相关阅读:
    【数模系列】01_聚类分析
    [翻译] 使用FXGL创建一个简单游戏 Pong (FXGL 11)
    硬盘分区管理软件,硬盘分区软件哪个好用
    简历上写的电商,那请问Redis 如何实现库存扣减操作和防止被超卖?
    Tmux教学【有图有代码】
    【VyOS-开源篇-3】- container for vyos 搭建 Halo 博客-vyos-开源篇
    POSIX线程使用signal模拟“中断“处理流程
    ky10 server arm 在线编译安装openssl3.1.4
    【Git企业开发】第一节.Git 的分支管理
    Elasticsearch:过滤搜索结果 - filter 及 post_filter
  • 原文地址:https://blog.csdn.net/Dragonlongbo/article/details/134351781