Kotlin入门第四节

List集合

  • API和JAVA基本类似,列举两个Kotlin的特殊API使用,是不可变集合
package com.fyx.s1


fun main() {
    var list = listOf<String>("1", "2", "3", "4")

    //如果有报错就会进入第二个函数
    var tag = list.getOrElse(0, {
        "索引越界了"
    })
    //如果获取报错那么则返回null
    var tag2 = list.getOrNull(20)
    println(tag2)

}

可变集合和非可变集合和集合转换

package com.fyx.s1


fun main() {
    //不可变集合 无add方法
    var list = listOf<String>("1", "2", "3", "4")


    //可变集合 有add方法
    var name = mutableListOf("123", "123123", "123213")
    name.add("123")
    
    
    //可变集合转换为不可变集合
    val toList = name.toList();
}

mutator函数学习

  • 我们可以使用mutator运算符去操作List对象的添加和修改
package com.fyx.s1


fun main() {
    //这里必须声明为val
    val name = mutableListOf<String>("ada", "ccc", "eee")
    //mutator特性,底层就是对运算符的重载
    name += "fff"
    println(name)
    name -= "ada"
    println(name)
}

集合遍历

package com.fyx.s1


fun main() {
    //这里必须声明为val
    val name = mutableListOf<String>("ada", "ccc", "eee")
    
    
    //常规遍历
    for (data in name) {
        println("数据是$data")
    }
    
    //函数遍历
    name.forEach {
        println("foreach遍历$it ")
    }

    //函数索引遍历
    name.forEachIndexed { item, index ->
        println("索引是$index 值是$item")
    }


}

结构语法解析过滤

package com.fyx.s1


fun main() {
    //这里必须声明为val
    val name = mutableListOf<String>("ada", "ccc", "eee")

    //结构语法解析
    var(name1,name2,name3) =name
    println(name1)
    
    //结构语法过滤_ 不取第一个元素
    var(_,name5,name6) =name
}

不可变不重复元素集合

package com.fyx.s1


fun main() {
    //这里必须声明为val
    val name= setOf<String>("123","123","321")

    //天然去重
    println(name.size)

    //获取元素
    println(name.elementAt(1))

    //防止索引越界等其它异常
    name.elementAtOrElse(7,{"索引越界了"})

}

可变不重复集合

package com.fyx.s1


fun main() {
    //这里必须声明为val

    val name = mutableSetOf<String>("123", "123", "1232")

    name += "123213"
    name += "123213231"
    name.add("1123")
    println(name)

}

集合转换

package com.fyx.s1


fun main() {
    //这里必须声明为val
    val name = mutableListOf<String>("123", "123", "1232")
    println(name.size)
    val toSet = name.toSet();
    println(toSet.size)


    //函数去重 底层还是将数据转为Set去重
    val names = mutableListOf<String>("123", "123", "1232")
    println(names.distinct().size)

}

Map定义和使用

fun main() {

    //基础定义添加值
    var name = mapOf<String, Double>("Key" to (562.21), "Tom" to (27.12))
    //通过Paid函数添加
    var names = mapOf<String, Double>(Pair("Key", 29.22))

    //获取key值
    var value = name["Key"]
    println(value)
    val get = name.get("Key")
    println(get)

    //获取空值返回报错
    val orDefault = name.getOrDefault("Noexit", -1);
    val orElse = name.getOrElse("Noexit", { "测试" })

    //循环遍历1
    for (entry in name) {
        println("key值是${entry.key} value值是${entry.key} ")
    }

    //循环遍历2
    name.forEach {
        println("key值是${it.key} value值是${it.key} ")
    }
    //循环遍历3
    name.forEach { k,v ->
        println("key值是${k} value值是${v} ")
    }
}

可变Map使用

package com.fyx.s1

fun main() {
    val map: MutableMap<String, Int> = mutableMapOf()
    map += Pair("kavin", 13)
    map.put("Kavens", 15)

    //如果获取不到就添加 Kavenss和20
    map.getOrPut("Kavenss", { 20 })
}

创建对象和字段Kotlin的内部流程

package com.fyx.s1

class Person {
    //类比java 中的 @notnull private String name="" 并生成get set 函数
    var name: String = ""

    //类比java 中的  private String name="" 并生成get set 函数
    var age: Int? = null

    //当声明为val 那么该字段只有get函数,意思是在对象初始化的时候就要赋值
    val names = "String"

    //重写get函数,返回1-100中的数据
    val age12: Int
        get() = (1..100).shuffled().first();

    fun getNum(): String {
        return age?.let {
            "我是有值的$it"
        } ?: "我是没值的"
    }
}

fun main() {
    //Person person1= new Person
    var person1 = Person()
    //类比setAge("18")
    person1.age = 20
    //类比getAge
    val age = person1.age
    println(age)

    //计算属性
    println(person1.age12)

    //防范竞态条件 如果该参数可能是空的情况下那么就会强制要求程序员完成非空的逻辑判断
    println(person1.getNum())
}

对象构造函数的使用

package com.fyx.s1


//构造函数里面的值是临时变量,需要声明对应的成员变量才能够使用
class KtBase2(_name: String, _age: Int, _sex: String) {
    var name = _name
    var age = _age
    var sex = _sex

    fun shoumes() {
        this.name
        this.age
        this.sex
        println("${this.name}${this.age}${this.sex}")
    }
}

fun main() {
    var person1 = KtBase2(_name = "西野", _sex = "男性", _age = 18)
    person1.shoumes()

}
  • 当然这样的写法也是很复杂的,kotlin为我们提供了更简化的操作只需要在临时变量里面加var 或者val修饰符就默认为我们生成字段,和get&set方法
package com.fyx.s1


//构造函数里面的值是临时变量,需要声明对应的成员变量才能够使用
class KtBase2(_name: String, _age: Int, _sex: String) {
    var name = _name
    var age = _age
    var sex = _sex

    fun shoumes() {
        this.name
        this.age
        this.sex
        println("${this.name}${this.age}${this.sex}")
    }
}

fun main() {
    var person1 = KtBase2(_name = "西野", _sex = "男性", _age = 18)
    person1.shoumes()

}


package com.fyx.s1


//构造函数里面的值是临时变量,需要声明对应的成员变量才能够使用
class KtBase2(var name: String,var age: Int,var sex: String) {


    fun shoumes() {
        this.name
        this.age
        this.sex
        println("${this.name}${this.age}${this.sex}")
    }
}

fun main() {
    var person1 = KtBase2(name = "西野",sex = "男性", age = 18)
    person1.shoumes()

}

主构造,和次构造

  • 类()是主构造函数, constructor是次构造函数,此构造总是需要调用主构造的方法
fun main() {
    var person1 = Kt1(name = "范", age = 12)
    var person2 = Kt1(age = 12, name = "范", sex = 2)
    person1.tostring()
    person2.tostring()

}

//这里注意已经存在name 和age字段 主构造可以直接生成,而此构造函数是不能使用var 或者val关键字的
class Kt1(var name: String, var age: Int) {
    var sex: Int? = null

    //次构造函数
    constructor(name: String, age: Int, sex: Int) : this(name, age) {
        this.sex = sex
    }

    fun tostring() {
        println("${this.age}${this.name}${this.sex?.let { it } ?: "我没值"}")
    }
}

init和构造器执行顺序

  • 调用次构造发现也是先走住构造函数
package com.fyx.s1

import sun.plugin.dom.core.Text


//构造器执行顺序,init相当于java的构造器{}
class KtBase2(var name: String, var age: Int, var sex: String) {
    
    init {
        println("主构造执行了")
    }

    constructor(name: String, age: Int) : this(name, age, "28") {
        println("次构造执行了")
    }
}

fun main() {
    var person1 = KtBase2(name = "西野", age = 18)
    println(person1.sex)
}

构造调用执行顺序

//第一步调用主构造
class Animal(_name: String, val age: Int) {

    //第二部
    //和初始代码块儿并行执行,谁在前谁先执行
    val name = _name

    //第二部
    //和字段码块儿并行执行,谁在前谁先执行
    init {
        val sortName = _name
        println("初始块儿执行了$sortName")
    }

    //第二部
    //和初始代码块儿并行执行,谁在前谁先执行
    val desc: String = "个人简介"

    //第三步
    constructor(_name: String, age: Int, sex: Int) : this(_name, age) {
        println("调用次代码块儿")
    }
}


fun main() {
    //代码执行顺序
    val animal = Animal("老王", 19, 2)
    println(animal.name)
}

惰性加载1

  • 使用lateinit 关键字延迟加载(注:惰性加载的字段必须是var,因为val在初始化就要赋值)
class Person() {
    //懒加载
    lateinit var name: String

    fun show1() {
        //直接调用懒加载的数据会报错
        //println(name)
        if(::name.isInitialized) println("初始化过了") else println("没初始化过")
    }
}

fun main() {
    var person1 = Person();
    person1.show1()
}

惰性加载2

  • 这里我们发现运行的时候加载中就已经输出了,五秒后才会返回值
class Person() {
    //饿汉式
    val name = createData()
    private fun createData(): String {
        println("加载中............")
        println("加载中............")
        println("加载中............")
        println("加载中............")
        println("加载中............")
        return "老王数据已加载"
    }

}

fun main() {
    var person1 = Person();
    Thread.sleep(5000)
    println(person1.name)
}

惰性加载3

  • 懒汉式 在用到的时候才会执行
class Person() {
    //懒汉式
    val name by lazy { createData() }
    private fun createData(): String {
        println("加载中............")
        println("加载中............")
        println("加载中............")
        println("加载中............")
        println("加载中............")
        return "老王数据已加载"
    }

}

fun main() {
    var person1 = Person();
    Thread.sleep(5000)
    println(person1.name)
}
posted @ 2022-04-12 17:02  xiye1  阅读(20)  评论(0)    收藏  举报