Kotlin从0到1,让你一周快速上手!!

声明

大家好,这里是懒羊羊学长,如果需要pdf版以及其他资料,请加入群聊。群里每天更新面经、求职资料,经验分享等,大家感兴趣可以加一下。
在这里插入图片描述

Kotlin

    • 声明
    • 1.Kotlin基础
    • 2. Kotlin函数
    • 3.Kotlin进阶
    • 4.Kotlin集合
    • 5.Kotlin高级
    • 6.kotlin实战
      • 6.1协变 逆变
    • 7. 手写内置函数
      • 7.1 Kotlin的单例模式
      • 7.2 Kotlin的注解
      • 7.3 手写RxJava

1.Kotlin基础

  • Kotlin的空指针检查
    var name:String?=null//村民1使用null//TODO 第一种补救措施,变量后边加上?,这样的话name如果真的是null,后边就不会执行,就不会引发空指针异常name?.length//TODO 第二种补救措施,不论name是不是null,都会执行name!!.length//TODO 第三种补救措施 ,(和Java一样)if(name!=null){name.length}
  • var 和val
 //TODO val修饰的变量只读不能改  var修饰的变量可读可改  我们修饰变量时尽可能用val修饰
  • 类型推断(函数也可以类型推断)
fun main(){//TODO 类型推断val name:String="Derry"val info:String ="真的很帅"val name1="Derry"val age=35val sex='c'//kotlin在编译期就决定好了类型,那么他就是静态语言。
}
fun add(number1:Int,number2:Int)=number1+number2
  • Java中称为方法,kotlin中称为函数,可以写在类的外面

  • Kotlin内置数据类型 这些在Java里边相当于一个包装类
    String 字符串
    Char 单字符
    Boolean true、false
    Int 整数
    Double 小数
    List 元素集合
    Set 无重复的元素集合
    Map 键值对的集合

  • 编译时常量

const val PI=3.14 //编译时常量,不能放在函数里边。如果在函数里边的话只能在运行时运行,何来编译时常量之说。
fun main(){val infoValue="Derry is Ok" //这个是只读类型的变量,并不能成为编译时常量println(infoValue)//只能读取,只读类型}
  • kotlin引用数据类型
const val PI=3.14 //编译时常量,不能放在函数里边。如果在函数里边的话只能在运行时运行,何来编译时常量之说。
fun main(){val infoValue="Derry is Ok" //这个是只读类型的变量,并不能成为编译时常量println(infoValue)//只能读取,只读类型}
  • range表达式
package com.example.myapplication.kotlinlearn
//TODO  kotlinrange表达式讲解
class kt13 {}
fun main(){val number=148//range 范围从哪里到哪里if(number in 10..59){println("分数不及格")}else if(number in 0..9){println("分数不及格并且分数很差")}else if (number in 60..100){println("分数合格")}else if (number !in 0..100){println("分数不在1到100范围内")}
}
  • when表达式
package com.example.myapplication.kotlinlearn//TODO when表达式详解
class kt14 {
}fun main() {//Java中if语句是执行代码//Kotlin中是表达式,能够有返回值val week = 1val resultInfo = when (week) {1 -> "星期一"2 -> "星期二"3 -> "星期三"4 -> "星期四"5 -> "星期五"6 -> "星期六"7 -> "星期日"else -> "不知道星期几了"}println(resultInfo)
}
  • String模板
package com.example.myapplication.kotlinlearnclass kt15 {
}//TODO 15.String 模板
fun main() {val garden = "梅溪湖公园"val time = 6println("今天天气很晴朗,去玩" + garden + "玩了" + time + "小时")//Java的写法println("今天天气很晴朗,去玩$garden,玩了${time}小时")//String模板的写法//KT是表达式println()val isLogin = falseprintln("resposne result:${if (isLogin) "恭喜" else "不恭喜"}")
}

2. Kotlin函数

  • 函数格式
package com.example.myapplication.kotlinlearn02class K1Base {
}//TODO 16.Kotlin的函数头讲解
fun main() {method01(1, "33")
}//函数不加修饰符的话默认就是public
//kotlin函数是先有输入,再有输出
private fun method01(age: Int, name: String): Int {println("name$name,age:$age")return 200
}
  • 默认参数
package com.example.myapplication.kotlinlearn02class K1Base {
}//TODO 16.Kotlin的函数头讲解
fun main() {method01(1, "33")
}//函数不加修饰符的话默认就是public
//kotlin函数是先有输入,再有输出
private fun method01(age: Int, name: String): Int {println("name$name,age:$age")return 200
}
  • 具名函数参数
package com.example.myapplication.kotlinlearn02class K1Base {
}//TODO 16.Kotlin的函数头讲解
fun main() {method01(1, "33")
}//函数不加修饰符的话默认就是public
//kotlin函数是先有输入,再有输出
private fun method01(age: Int, name: String): Int {println("name$name,age:$age")return 200
}
  • Unit关键字
package com.example.myapplication.kotlinlearn02class kt19 {
}//TODO KotlinUnit函数的特点
fun main() {val r: Unit = doWork()println(r)}//:Unit不写默认也有,相当于无参数返回 忽略类型 相当于Java里的void,Unit是一个类型 不是关键字
private fun doWork(): Unit {}
  • Nothing关键字
package com.example.myapplication.kotlinlearn02class kt19 {
}//TODO KotlinUnit函数的特点
fun main() {val r: Unit = doWork()println(r)}//:Unit不写默认也有,相当于无参数返回 忽略类型 相当于Java里的void,Unit是一个类型 不是关键字
private fun doWork(): Unit {}
  • 反引号的使用
package com.example.myapplication.kotlinlearn02
//TODO kotlin反引号特点讲解class kt21 {
}private fun a() {//1 '方法名' 用反引号写的kotlin方法名在低版本的时候是可以使用的,但先高版本已经废弃了kt21.`is`()//如果别的Java文件里恰好定义了这两个方法,那么得用反引号括起来kt21.`in`()//3.第三种情况//private fun `2123456`(){  加密函数作用,维护一个文档,里边写明这个函数的饿作用////}}private fun `2123456`() {}
  • 匿名函数
package com.example.myapplication.kotlinlearn02//TODO 22.匿名函数讲解
fun main() {//没有名字的函数是匿名函数val length = "derry".count() {//  由于没有名字,会默认给这个Char类型,一个名字,一般情况下 都是it。传入参数是把字符串的每一个字符依次传入进来it == 'r'}println(length) //这里会打印出2,因为字符串中只有两个字符是满足lambda表达式的条件}
  • Kotlin函数类型
package com.example.myapplication.kotlinlearn02class kt23 {
}//TODO 23.Kotlin的函数类型和隐式返回讲解
fun main() {val methodAction: () -> String//函数的输入与输出的声明  声明区域methodAction = { //实现区域"xyr" //匿名函数不用写return 以最后一行作为返回值}//调用函数println(methodAction())println(methodAction.invoke()) //这种调用方式仅限于lambda,普通函数就不支持这种方式了
}fun methodAction(): String //声明区域
{return "xyz" //实现区域
}
  • lambda函数的参数
package com.example.myapplication.kotlinlearn02fun main() {//第一步:函数输入  输出 和声明,第二步是函数的实现val methodAction: (Int, Int, Int) -> String = { number1, number2, number3 -> //大括号里是函数的实现"number1:$number1,number2:$number2"}//第三步调用println(methodAction(1, 2, 3))
}//真正的函数
fun methodAction(number1: Int, number2: Int, number3: Int) {}
  • it关键字的用法
package com.example.myapplication.kotlinlearn02fun main() {//第一步:函数输入  输出 和声明,第二步是函数的实现val methodAction: (Int, Int, Int) -> String = { number1, number2, number3 -> //大括号里是函数的实现"number1:$number1,number2:$number2"}//第三步调用println(methodAction(1, 2, 3))
}//真正的函数
fun methodAction(number1: Int, number2: Int, number3: Int) {}
  • 匿名函数类型推断
package com.example.myapplication.kotlinlearn02//TODO 26.Kotlin的匿名函数类型自动推断
fun main() {//val fun2: () -> Unit//fun1 必须指定参数类型和返回类型val fun1 = {println("你好")}//如果没有指定,则以最后一行作为返回值类型val fun3 = { v1: Double, v2: Float, v3: Int ->"啦啦啦v1$v1,v2$v2,v3$v3"}//fun3 就是(Double,Float,Int)->String 这个类型  ,fun4并不是匿名函数,只是一个变量,后边的函数体才是匿名函数println(fun3(2.2, 3f, 5))fun1.invoke()
}
  • lambda表达式
package com.example.myapplication.kotlinlearn02//TODO 27.Kotlin的lambda的表达式
fun main() {//匿名函数val fun1 = {}//匿名函数等价于后边要讲的Lambdaval addResultFun = { number1: Int, number2: Int ->println("两个数相加的结果是${number1 + number2}")}val weekResult: (Int) -> Any = { number: Int ->when (number) { //when关键字也可以作为一个返回值1 -> "星期一"else -> -1}}
}
  • 函数中定义参数是函数包函数
package com.example.myapplication.kotlinlearn02//TODO 28.函数中定义参数是函数包函数
fun main() {//用户loginAPI("Derry", "123456") { msg, code ->println("用户最终登录的成果如下msg:$msg,code是:$code")}
}//模拟:数据库SQLServer
const val USER_NAME_SAVE_DB = "Derry"
const val USER_PWD_SAVE_DB = "123456"//模拟,登录API前端
public fun loginAPI(userName: String, userPwd: String, responseResult: (String, Int) -> Unit) {if (userName == null || userPwd == null) {TODO("用户名密码是null")}responseResult.invoke(userName, 3)
}
  • 内联函数
package com.example.myapplication.kotlinlearn02//TODO 内联函数
fun main() {//TODO 如果函数没有内联,那么在调用端,会生成多个对象来完成Lambda的调用(会造成性能的损耗)//TODO 如果此函数使用内联,在调用端会采用宏替换,替换到调用处,好处(没有任何函数开辟、对象开辟等性能的损耗)//如果一个函数里的参数有Lambda,那么,就需要声明内联//TODO 如果函数参数有Lambda,尽量使用inline修饰,这样内部会做优化,减少函数、对象开辟的损耗。
}
  • 函数引用
package com.example.myapplication.kotlinlearn02//TODO 31,函数引用类型调用
fun main() {//方式一login("张三", "123") { msg, code ->{}//函数引用环节  ,函数通过函数引用::来变成函数类型的对象login("张三", "李四", ::responseResultImp)}
}fun responseResultImp(msg: String, pwd: Int): Unit {}inline fun login(name: String, pwd: String, resposneResult: (String, Int) -> Unit) {}
  • Kotlin中函数类型作为返回值类型
package com.example.myapplication.kotlinlearn02//TODO 32.Kotlin的函数类型作为返回类型
fun main() {val result = showFun("你好")//result是个函数类型result("dd", 3)}fun show(info: String): Boolean {  //函数返回Boolean值return false;
}fun showFun(info: String): (String, Int) -> String {println("我是show函数info:$info")return { name, age ->"name=$name,age=${age}"}
}
  • 匿名函数和具名函数
package com.example.myapplication.kotlinlearn02//TODO 33.Kotlin中的匿名函数和具名函数
fun main() {//匿名函数showPersonInfo("Derry", 38, '男', "学习KT语言中") {println(it)}println()//具名函数showPersonInfo("Derry", 38, '男', "学习KT语言中", ::showResultImpl)}fun showResultImpl(it: String) {println("显示具名:$it")
}inline fun showPersonInfo(name: String,age: Int,sex: Char,study: String,showResult: (String) -> Unit
) {val str = "name:$name,age:$age,sex:$sex,study:$study"showResult(str)//这个lambda只是起了一个名字,并不是一个真正的函数,真正的实现是上边的println语句}
  • kotlin可空的特性
package com.example.myapplication.kotlinlearn03//TODO 34.Kotlin语言可空性的特点
fun main() {//TODO name不能为空,如果为空,编译会报错var name: String = "Derry"//TODO 第二种情况 声明的时候指定为可空var name2: String? = "Derryhello"name2 = nullprintln(name2?.length)//如果name2为null,就不执行?后边的区域
}
  • kotlin安全调用操作符
package com.example.myapplication.kotlinlearn03import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.capitalize//TODO 35.Kotlin语言的安全调用操作符
fun main() {var name: String? = "xuyuanzhi"val c = name?.capitalize() //name是可空类型,可能是null,如果想要使用name,必须给出补救措施//如果name是Null,就不会执行?后边的区域代码,所以就不会崩溃。println(c)
}
  • Kotlin中带let的安全调用
package com.example.myapplication.kotlinlearn03//TODO 36.kotlin中使用带let的安全调用
fun main() {val name: String? = null//如果name真的是null,就不执行?.let{}这一大块区域的代码var r = name?.let {// it==name本身,所以是String类型的if (it.isBlank()) {"Default"} else {"[$it]"}}println(r)
}
  • Kotlin中的非空断言操作符
package com.example.myapplication.kotlinlearn03import androidx.compose.ui.text.capitalize//TODO 37.Kotlin语言中的非空断言操作符
fun main() {var name: String? = nullname!!.capitalize()//!!是断言,不管name是不是null,都会执行.capitalize(),所以就报空指针异常了,所以要慎用//结论,如果百分百能够保证name是有值的,才能使用!!(否则有Java空指针异常),否则进来使用?
}
  • if判断null值的情况
package com.example.myapplication.kotlinlearn03//TODO kotlin中使用if判断Null值情况
fun main() {var name: String? = null//if(补救措施)if (name != null) {var r = name.capitalize()println(r)} else {println("name is null")}
}
  • Kotlin的空合并操作符
package com.example.myapplication.kotlinlearn03//TODO kotlin中使用if判断Null值情况
fun main() {var name: String? = null//if(补救措施)if (name != null) {var r = name.capitalize()println(r)} else {println("name is null")}
}
  • 异常处理与自定义异常
package com.example.myapplication.kotlinlearn03//TODO kotlin中使用if判断Null值情况
fun main() {var name: String? = null//if(补救措施)if (name != null) {var r = name.capitalize()println(r)} else {println("name is null")}
}
  • kotlin中先决条件函数
package com.example.myapplication.kotlinlearn03//TODO 41.kotlin中的先决条件函数
fun main() {val value1: String? = nullvar value2: Boolean = falsecheckNotNull(value1)  //抛个异常requireNotNull(value1)//require(value2) {println("我是傻逼")}}
  • kotlin中的substring
package com.example.myapplication.kotlinlearn03
//TODO 42.Kotlin中的substringconst val INFO = "xyz is Success"
fun main() {val indexOf = INFO.indexOf('i')println(INFO.substring(0, indexOf))println(INFO.substring(0 until indexOf))
}
  • 43 kotlin中的split操作
package com.example.myapplication.kotlinlearn03//TODO 43.Kotlin语言的split操作
fun main() {val jsonText = "x1,x2,x3,x4"val list: List<String> = jsonText.split(',')println("分割后的list里面的元素有${list}")list.forEach {println(it)}//C++解构 KT也有解构val (v1: String, v2, v3, v4) = listprintln("$v1,$v2,$v3,$v4")
}
  • kotlin中使用repace完成加密解密的操作
package com.example.myapplication.kotlinlearn03//TODO 44.Kotlin中的replace完成加密解码操作
fun main() {val sourcePwd = "AbcdefdsAKMNOfafadfagg"println("原始密码为:$sourcePwd")val newPwd = sourcePwd.replace(Regex("AKMNO")) {"-"}println(newPwd)//解密操作val sourcePwdNew = newPwd.replace(Regex("[-]")) {when (it.value) {"-" -> "AKMNO"else -> it.value}}println("解密后的密码为$sourcePwdNew")
}
  • kotlin中==和===的比较
package com.example.myapplication.kotlinlearn03//TODO 45.Kotlin中 ==与===的比较
fun main() {// ==是内容的比较。相当于Java的equals//===是引用的比较val n1: String = "aaa"val n2: String = "aaa"println(n1.equals(n2))println(n1 == n2)println(n1 === n2)
}
  • kotlin中字符串的遍历操作
package com.example.myapplication.kotlinlearn03//TODO 46.Kotlin中字符串的遍历操作
fun main() {val str = "abcdefg"str.forEach {println("字符是$it")}
}
  • Kotlin中数字类型安全转换操作符
package com.example.myapplication.kotlinlearn03//TODO 47.Kotlin中数字类型的安全转换函数
fun main() {val number: Int = "666".toInt()println(number)//如果转换成Int成功就返回Int,如果转换失败就返回Nullval number2: Int? = "666.6".toIntOrNull()println(number2)
}
  • Double与Int类型相互转化
package com.example.myapplication.kotlinlearn03import kotlin.math.roundToInt//TODO 48.Double转Int与类型格式化
fun main() {println(65.4.toInt()) //toInt没有四舍五入的效果,是取低位的println(66.8.roundToInt())//roundToInt有四舍五入的效果,”%“val r: String = "%.3f".format(66.5554511)//后边保留小数点后三位println(r)
}

3.Kotlin进阶

  • apply函数的用法
package com.example.myapplication.kotlinlearn03import androidx.compose.ui.text.toLowerCase//TODO 49.Kotlin中apply的内置函数
fun main() {val info = "Derry is successful"//普通传统方式println(info.length)println("info的最后一个字符是${info[info.length - 1]}")println("info全部转化成小写${info.toLowerCase()}")//apply方式info.apply {//一般大部分情况下,匿名函数都会持有一个it,但是apply不会持有it,但会持有this     this==info本身//apply函数始终是返回info本身String类型println(this)println(length)println("info的最后一个字符是${this[length - 1]}")println("info全部转化成小写${this.toLowerCase()}")}//TODO apply函数的写法规则如下//apply函数始终返回info本身,所以可以进行链式调用info.apply {println("info的长度是${this.length}")}.apply {println("info的最后一个字符是${this[length - 1]}")}.apply {println("info全部转化成小写${this.toLowerCase()}")println(readLine())}//TODO 结论 apply的返回值 谁.apply,返回谁本身//apply里没有it,只有this,this==xxx本身//TODO 用法,使用中,不需要用apply的返回值,而是尽量使用链式调用,功能分层
}
  • let函数
package com.example.myapplication.kotlinlearn03//TODO 50.kotlin语言let的内置函数
//普通方式 对集合第一个元素相加
//let方式 对集合第一个元素相加
//普通方式 对值判null 并返回
//let方式 对值判null 并返回
fun main() {val list: List<Int> = listOf(1, 2, 3, 4)val value1 = list.first()println(value1 + value1)//TODO let方式对集合第一个元素相加listOf(1, 2, 3, 4).let {//it ==集合本身//let作为内置函数,会以最后一行作为返回值it.first() + it.first()}//TODO apply总结//1.apply函数的返回类型 永远是调用者本身//2. apply函数的匿名函数体{持有的是this==info本身}//TODO let总结// 1.let函数的返回值是 函数最后一行的返回值// let函数持有的是it,it等于调用者本身//TODO 普通方式,对值判null 并返回//TODO let解决对值判null 并返回}fun get(value: String?): String {return value?.let {  //如果value为null 则不会执行函数体里的东西,如果不为null  ,则执行?:后边的东西"欢迎${value}回来"} ?: "你传递的是null"
}//简化版本
fun get2(value: String?) = value?.let {  //如果value为null 则不会执行函数体里的东西,如果不为null  ,则执行?:后边的东西"欢迎${value}回来"
} ?: "你传递的是null"
  • run函数的综合案例
package com.example.myapplication.kotlinlearn03//TODO 51.Kotlin语言中run内置函数
fun main() {//1.run函数的特点 字符串演示val str = "xyz is successful"//TODO run函数的返回,根据匿名函数str.run {//以最后一行作为返回值,run函数函数体持有this,this==调用者本身"a"}//TODO 2.具名函数判断长度//这个是匿名函数str.run {}//这个是具名函数,配合runstr.run(::isLong) //this==str.run(::showText) //this==isLong函数返回类型Boolean的值本身.run(::mapTest).run {println(this)}println()//TODO 上面的函数全部是具名函数调用给run运行str.run {if (length > 5) true else false}.run {if (this) "你的字符串合格" else "你的字符串不合格"}.run {"$this"}.run {println(this)}}fun isLong(str: String) = if (str.length > 5) true else false
fun showText(isLong: Boolean) = if (isLong) "你的字符串合格" else "你的字符串不合格"fun mapTest(str: String) = "[$str]"
  • with操作符
package com.example.myapplication.kotlinlearn03//TODO 52.kotlin中with函数
fun main() {//TODO 和run函数是一模一样  持有thisval n1 = "hello"with(n1) {//this==str本身}val result1: Int = with(n1, ::getStrLenAction)val result2: String = with(n1, ::getStrInfo)//匿名操作with(with(n1) {n1.length}) {"你的字符串长度为$this"}}fun getStrLenAction(str: String) = str.lengthfun getStrInfo(str: String) = str
  • also的用法
package com.example.myapplication.kotlinlearn03import androidx.compose.ui.text.toLowerCase//TODO also操作符
//  str.also和apply差不多,永远是返回调用者本身
fun main() {val str = "XUYUANZHI"val r1: String = str.also {}.also {//可以链式调用it == "a"}str.also {println("str的原始值是$it")}.also {println("str转换成小写的效果是${it.toLowerCase()}")}
}
  • takeif操作符
package com.example.myapplication.kotlinlearn03//TODO 54.takeIf海曙的使用
fun main() {val name: String? = "aa"val result = name.takeIf {false}//如果为true,这个表达式返回name本身,如果为false,则返回nullprintln(result)//企业用法,takeif+空合并操作符name.takeIf { true } ?: "权限不够,被拒绝访问"
}//TODO  总结:一般大部分情况下,都是takeIf+空合并操作符
  • takeunless函数
package com.example.myapplication.kotlinlearn03//TODO 55.takeUnless
fun main() {"aaa".takeUnless {false} ?: "未经过任何初始化的值"//takeUnless和takeif判断条件相反,但是效果一样//false会返回调用者本身,true会返回null
}

4.Kotlin集合

  • list的创建与获取
package com.example.myapplication.kotlinlearn03//TODO 56.Kotlin语言的list创建与元素获取
fun main() {val list: List<String> = listOf("张三", "李四", "王五")//普通取值方式  ,索引println(list[0])println(list[1])println(list[2])println(list.get(0))println(list.get(1))println(list.getOrElse(2) { "越界" })println(list.getOrElse(3) { "越界了" })println(list.getOrNull(20))println(list.getOrNull(2333) ?: "你越界了哦")//总结:开发过程中,尽量使用getOrElse 或者  getOrNull 才能体现出Kotlin中的亮点
}
  • 可变list集合的学习
package com.example.myapplication.kotlinlearn03//TODO 57.Kotlin可变List集合学习
fun main() {val list: MutableList<String> = mutableListOf("Derry", "zhangsan", "lisi")//可变的集合list.add("赵六")list.remove("lisi")println(list)//不可变集合val list2: List<Int> = listOf(123, 456, 789)println(list2)//不可变转为可变集合val list3: MutableList<Int> = list2.toMutableList()//可变集合变为不可变集合val list4 = list3.toList() //无法完成可变的操作//小结:KT语言中,分为可变集合与不可变集合 ,Kotlin中更加推荐使用不可变集合,防止造成数据丢失
}
  • mutator学习
package com.example.myapplication.kotlinlearn03//TODO 58.Kotlin语言的mutator函数学习
fun main() {//1.mutator += -=操作val list: MutableList<String> = mutableListOf("Derry", "DerryAll", "zhangsan", "lisi")list += "张三"list -= "李四"println(list)//2.removeIf
//    list.removeIf{ //如果是true,自动遍历整个可变集合,一个一个元素的删除
//        true
//    }list.removeIf {it.contains("D")  //过滤包含D的元素}println(list)
}
  • list集合的遍历
package com.example.myapplication.kotlinlearn03//TODO 59.List集合遍历学习
fun main() {val mList: List<Int> = listOf<Int>(1, 2, 3, 4, 5, 6)println(mList)//输出list详情而已,不是遍历集合//第一种遍历for (item: Int in mList) {println("item:$item")}//第二种遍历mList.forEach {//it==每一个元素println("item:$it")}//第三种方式mList.forEachIndexed { index, i ->println("下标是$index,值是$i")}
}
  • kotlin中解构语法过滤元素学习
package com.example.myapplication.kotlinlearn04//TODO 60.Kotlin语言解构语法过滤元素学习
fun main() {val list: List<String> = listOf("李元霸", "李小龙", "李连杰")var (v1, v2, v3) = listvar (_, va1, va2) = list //_不是变量,是用来过滤结构赋值的,拒收值,不接收赋值给我
}
  • 61Set元素的创建与获取
package com.example.myapplication.kotlinlearn04//TODO 61.Kotlin中Set创建与元素获取
//set 定义不允许重复
//
fun main() {val set: Set<String> = setOf("张三", "李四", "王五", "李四")println(set)println(set.elementAt(0))println(set.elementAt(3))//越界 ,会崩溃println()println(set.elementAtOrElse(3) { "越界了" })println(set.elementAtOrNull(3)) //得不到会返回null}
  • 可变集合set
package com.example.myapplication.kotlinlearn04fun main() {val set: MutableSet<String> = mutableSetOf("李元霸", "李连杰")set += "张三"set -= "李四"set.remove("王五")
}
  • Kotlin集合转换和快捷函数学习
package com.example.myapplication.kotlinlearn04//TODO 63.Kotlin语言集合转换和快捷函数学习
fun main() {//1.定义可变list集合val list: MutableList<String> = mutableListOf("张三", "李四", "王五")println(list)//2.list转set自动去重val set: Set<String> = list.toSet()println(set)//4.快捷函数去重distinctprintln(list.distinct())
}
  • Kotlin中的数组类型
package com.example.myapplication.kotlinlearn04
//TODO 64.Kotlin中的数组类型
// IntArray  inArrayOf
// DoubleArray  doubleArrayOffun main() {val intArray = intArrayOf(1, 2, 3, 4)println(intArray[1])println(intArray.elementAtOrNull(0) ?: "aaa")//尽量不会崩溃//OrNull要配合空合并操作符来使用println(intArray.elementAtOrElse(55) { 3 })//TODO 3.List集合转数组listOf<Char>('a', 'b', 'c', 'd').toCharArray()}
  • map集合
package com.example.myapplication.kotlinlearn04import androidx.compose.animation.scaleOut//TODO 65.Kotlin中Map的创建
fun main() {//第一种方式val map1: Map<String, Double> = mapOf<String, Double>("xuyuanzhi" to 22.3, "lal" to 33.3)//第二种方式val map2 = mapOf(Pair("aaa", 33.2), Pair("ddd", 22.5))//TODO 读取map的值println(map1["xuyuanzhi"])//运算符重载了println(map1.get("xuyuanzhi"))//运算符重载//方式二println(map1.getOrDefault("xuyuanzhi", -1))println(map1.getOrDefault("xuyuanzhi") { -1 })//方式三,和Java一样,获取不到会崩溃println(map1.getValue("xuyuanzhi"))//TODO 遍历map的值//第一种方式map2.forEach {// it 每一个元素都是一个map,key value 结构。  it类型为 Map.Entry<String,Int>println("K:${it.key},V:${it.value}")}println()//第二种方式map2.forEach { key: String, value: Double -> //把it覆盖了println("key是$value,value 是 $value")}//第三种方式map2.forEach { (key: String, value: Double) ->println("key 是$key,value是$value")}//第四种方式for (item: Map.Entry<String, Double> in map2) {println("${item.key},value是${item.value}")}//TODO 可变集合Map的操作val map3: MutableMap<String, Int> = mutableMapOf(Pair("Derry1", 123), Pair("xuyuanzhi", 456))map3 += "aaa" to 23map3 += "BBB" to 45map3 -= "Derry"map3["cc"] = 888map3.put("Dddd", 999)//如果在map里没有找到999的元素,那么先把999添加到里边去,然后再从map里边获取999的元素map3.getOrPut("999") {66}println(map3)}
  • Kotlin的计算属性与防范竞态条件
package com.example.myapplication.kotlinlearn04//TODO 70.Kotlin语言的计算属性与防范竞态条件
class Derry {val number: Int = 0get() = field//计算属性 (field 永远是描述name的值),如果一个变量没有赋值,那么就没有field这个东西。//TODO 防范静态条件 当你调用成员,这个成员可能为null,可能为空值,就必须采用防范竞态条件,这个是KT编程的规范化// 防范静态条件尽量使用(?+内置函数+空合并操作符)var info: String? = nullfun getStudentInfo(): String {return info?.let { //info如果不为null,则执行let函数里的,如果为null,则执行?:后边的语句if (it.isBlank()) {"你原来是空值"} else {"$it"}} ?: "info你原来是null,请检查代码"}//,
}fun main() {//val修饰的变量 没有set函数Derry().number// 计算属性}
  • kotlin的主构造函数
package com.example.myapplication.kotlinlearn04//主构造函数:规范来说,都是增加_xxx的方式,临时的输入类型,不能直接用,需要接收下来,成为变量才能用
class Students(_name: String, _age: Int) {val name: String = _namefun show() {println("nieg")}
}//TODO 71.Kotlin语言的主构造函数学习
fun main() {val student = Students("张三", 56)
}
  • Kolin中的构造函数
package com.example.myapplication.kotlinlearn04class Student2(var name: String, var age: Int) { //主构造函数 ,推荐这样写//如果想完成多个构造函数重载的话,就用次构造才能做到//次构造函数必须调用主构造函数,否则编译不通过constructor(name: String) : this(name, 33) {}//三个参数的构造函数constructor(name: String, age: Int, sex: Char) : this(name, 33) {}}//TODO 构造函数的默认参数
// 主构造和次构造都有默认参数时,优先使用主构造,然后再使用次构造
class Animal(name: String = "啦啦啦") {val name = nameoverride fun toString(): String {println("ddd")return "aa"}
}fun main() {val s1 = Student2("张三", 18, '男') //调用三个参数的构造函数,首先会去先调用主构造函数,然后调用次构造函数val a1 = Animal()println(a1.toString())
}
  • 类的初始化顺序

在这里插入图片描述

package com.example.myapplication.kotlinlearn03//TODO 76.Kotlin语言构造初始化顺序学习
fun main() {//重点:Init代码块和类成员是同时生成的,
}
  • lateinit学习 延迟初始化
package com.example.myapplication.kotlinlearn04//TODO 77.Kolin里边延迟初始化lateinit学习
class kt77 {lateinit var name: String;fun show() {if (::name.isInitialized) {//判断name有没有初始化}}//TODO 我们再使用延迟初始化字段的时候,一定要用::name.isInitialized 这个来判断,因为这个字段一碰就会崩溃,所以不要随便用
}fun main() {}
  • by lazy 的使用
package com.example.myapplication.kotlinlearn04class k78 {val database: String by lazy {"aaa"  //只有用的时候才会加载}
}//TODO 78.惰性初始化by lazy
// lateinit 是在使用的时候,手动加载的懒加载方式,然后再使用
// by lazy  是在使用的时候,自动加载的懒加载方式,然后再使用
fun main() {}
  • 崩溃小陷阱
package com.example.myapplication.kotlinlearn04class kt79(_info: String) {val content: String = getInfoMethod()private val info = _infoprivate fun getInfoMethod() = info
}//TODO 1.陷阱一:如果init函数里要用到类属性,那么属性初始化要放在init函数之前
//  2.陷阱二:  类后边的函数要用到变量,要在这个函数之前进行初始化
// 3.陷阱三:  
// 总结:为了以后不出现陷阱三,所有的类成员都放到最前面就好了
fun main() {println("${kt79("Derry").content.length}")  //会崩,因为执行先执行构造方法,然后执行getInfoMentod,这个时候info还没有初始化,所以会崩}

5.Kotlin高级

  • 继承与重载的open关键字
package com.example.myapplication.kotlinlearn05import androidx.compose.animation.scaleOut
import com.example.myapplication.kotlinlearn04.Student2// public final class Person
// open 去除 final修饰open class Person(private val name: String) {  //构造参数私有化,子类不可访问private fun showName() = "父类的名字是$name"fun showName1() = "父类的名字是$name"open fun myPrintln(): Unit = println(showName())
}class Student(private val subName: String) : Person(subName) {private fun showName() = "子类的名字是$subName"override fun myPrintln(): Unit = println(showName()) //此函数以及被子类重写了}//TODO 82.Kotlin的继承与重载的open关键字
fun main() {val person: Person = Student("aa")person.myPrintln()println(person is Person)println(person is Student)// is +as 配合来使用if (person is Student) {//    (person as Person).myPrintln()  这个就算转换到父类,也是调用到子类的方法println((person as Person).showName1())}}
  • Kotlin类型转换
package com.example.myapplication.kotlinlearn05class kt84 {
}fun main() {//智能类型转换// xxx as xxx 从一个类型转换到另一个类型
}
  • Kotlin中Any类的超类
package com.example.myapplication.kotlinlearn05//TODO 85.Kotlin的Any超类
// 在kt中,所有的类都隐式继承了Any(),你不写默认就有
// 在Java中,所有的类都隐式集成了 extends Object,你不写 ,默认就有
// Any在Kotlin设计中,只提供标准,看不到实现,实现在各个平台处理好了
class Person3 {}fun main() {}
  • Kotlin对象声明
package com.example.myapplication.kotlinlearn05object kt86 {/*object 对象类背后做了什么public static final K86 INSTANCE;private K86() {} //主构造废除一样的效果static  {K86 var0=new k86()INSTANCE =var0//直接把init代码搬到这里来了,因为主构造函数被私有化,所以把东西搬到这里来了String var1="K86 init..."System.out.println(var1)}public final void show(){}*/
}//TODO 86.Kotlin的对象声明
fun main() {}
  • Kotlin中的对象表达式
package com.example.myapplication.kotlinlearn05open class kt87 {open fun add(info: String) = println("K87 add: $info")open fun del(info: String) = println("K87 del: $info")
}//TODO 87.Kotlin的对象表达式
fun main() {//TODO 匿名 对象表达式方式val p1: kt87 = object : kt87() {override fun add(info: String) {println("我是匿名表达方式$info")}override fun del(info: String) {println("我是匿名表达方式:$info")}}p1.add("aaa")p1.del("ddd")val p2: kt87 = k87Impl()p2.add("张三")p2.del("李四")//TODO 对Java的接口 用对象表达式方式val p3: Runnable = object : Runnable {override fun run() {println("Java Runnable run...")}}p3.run()val p4: Runnable = Runnable { //Kotlin不支持这种简洁方式,只有Java可以println("aaa")}p4.run()}class k87Impl : kt87() {override fun add(info: String) {println("我是具名函数add$info")}override fun del(info: String) {println("我是具名函数del${info}")}
}
  • kotlin中的伴生对象
package com.example.myapplication.kotlinlearn05class kt88 {companion object {//伴生对象 ,本身是一个静态内部类val name = "许远志"  //直接会生成静态的 private static final String name="许远志”val info = "lalala是吧"fun showInfo() = println("显示:$info")// public static final kt88.companion companion =new kt88.companion()//给外界调用的}
}//TODO 88.Kotlin的伴生对象,
//  伴生对象很大程度上和Java的static静态差不多的  不管kt88实例化多少次,伴生对象只加载一次,  伴生对象只初始化一次
fun main() {}
  • 内部类
package com.example.myapplication.kotlinlearn05//TODO 内部类
class Body() { //外部类val name: String = "aaa"class Heart { //嵌套类 加上inner修饰符才能变成内部类 ,val nameHeart: String = "bbb"fun show() {//println(name)}}
}//嵌套类的特点,外部的类能访问内部的嵌套类, 内部的嵌套类不能访问外部类的成员
// 内部类的特点: 内部的类能访问外部的类  外部的类能访问内部的类
class kt89 {inner class kt899 {}
}fun main() {//内部类kt89().kt899()//嵌套类Body.Heart()}
  • Kotlin的数据类
package com.example.myapplication.kotlinlearn05//普通类
class ResponseResultBean(var msg: String, var code: Int, var data: String) : Any()//TODO set get 构造函数
//相当于接收 服务器返回的JavaBean 现在kotlin叫做数据类
data class ResponseResultBean2(var msg: String, var code: Int, var data: String) : Any()//TODO  set get 构造函数  copy 克隆 toString hashCode  equals  结论:数据类 生成更加丰富
//TODO 90.Kotlin的数据类
fun main() {//TODO 1.ToString方法println(ResponseResultBean("aa", 12, "aa"))//普通类 toString 调用了windows打印的toStringprintln(ResponseResultBean2("aa", 12, "aa"))// 数据类 any,重写了父类的toString//TODO 2.==方法//普通类==的实现  Any父类的实现 是equals  是比较两个对象的引用//数据类==是值的比较,所以 内容一样就是true//TODO 总结:普通类的Any 的== 是引用的比较  数据类any的==被重写了 是值的比较}
  • Kotlin的解构操作
package com.example.myapplication.kotlinlearn05//普通类
class Student1(var name: String, var age: Int, var sex: Char) {//解构操作 必须从component1开始operator fun component1() = nameoperator fun component2() = ageoperator fun component3() = sex}class kt92 {
}//TODO 92.Kotlin的解构操作
fun main() {var (name, age, sex) = Student1("张三", 89, '男')//数据类默认就有解构操作}
  • Kt的运算符重载
package com.example.myapplication.kotlinlearn05
//TODO 93.Kotlin的运算符重载class AddClass(var number1: Int, var number2: Int) {operator fun plus(p1: AddClass) = (number1 + p1.number1) + (number2 + p1.number2)}fun main() {//运算符重载println(AddClass(2, 2) + AddClass(3, 3))
}
  • 枚举类
package com.example.myapplication.kotlinlearn05//枚举的值等于枚举本身
enum class Week {星期一,星期二,}fun main() {}
  • 枚举类型定义函数
package com.example.myapplication.kotlinlearn05data class LimbInfo(var limbInfo: String, var length: Int) {fun show() = println("$limbInfo,长度是 $length")
}enum class Limbs(private var limbsInfo: LimbInfo) {LEFT_HAND(LimbInfo("左手", 88)),//左手RIGHT_HAND(LimbInfo("左手", 88)),//左手; //结束枚举值fun show() = "四肢是${limbsInfo.limbInfo} ,长度是${limbsInfo.length}"fun update(limbsInfoUpdate: LimbInfo) {this.limbsInfo.limbInfo = limbsInfoUpdate.limbInfo //也可以更新枚举值,这个枚举值的对象是实例化的时候传进来的}
}//结论:枚举的主构造参数必须与枚举值保持一致
// 95.枚举类型定义函数
fun main() {println(Limbs.LEFT_HAND.show()) //枚举值的主构造参数不要管,是枚举值直接调用show来显示的}
  • Kotlin的代数数据类型
package com.example.myapplication.kotlinlearn05enum class Exam {Fraction1,//分数差Fraction2,//分数及格Fraction3,//分数良好Fraction4,//分数优秀;//枚举结束
}class Teacher(private val exem: Exam) {fun show() =when (exem) {Exam.Fraction1 -> "该学生的分数很差"Exam.Fraction2 -> "该学生的分数及格"Exam.Fraction3 -> "该学生的分数良好"Exam.Fraction4 -> "该学生的分数优秀"//不需要使用else ,由于我们的函数是用枚举类型来判断处理的,这个就属于代数数据类型,不需要写else了//因为when表达式非常明确了,只有四种类型,不会出现else其他,所以不需要写}
}//TODO 96.Kotlin的代数数据类型讲解
//定义
fun main() {}
  • 密封类
package com.example.myapplication.kotlinlearn05//密封类 :在于控制子类数量可控,以免被非法继承
// 枚举类:在于控制状态数量可控
//
sealed class kt97 {
}//TODO 97.密封类  我们的成员必须要有类型(object class)  2. 并且是继承本类
fun main() {}
  • 数据类使用条件
package com.example.myapplication.kotlinlearn05//TODO 98.数据类使用条件
// 数据类至少必须有一个参数的主构造函数  ;必须有val var 修饰的参数,数据类不能使用abstract,inner, open 等修饰
fun main() {}

6.kotlin实战

  • 接口的定义
package com.example.myapplication.kotlinlearn06interface IUSB {var usbVersionInfo: String //USB版本信息var usbInsertDevice: String// 插入的设备信息fun insertUSB(): String //被插入的动作
}open class Mouse(override var usbVersionInfo: String, override var usbInsertDevice: String) : IUSB {override fun insertUSB(): String {TODO("Not yet implemented")}}class shubiao : Mouse("aa", "a"), IUSB {override fun insertUSB(): String {return super.insertUSB()}}//TODO 99.Koltin的接口定义详解
// 1.接口里面和接口本身都是public  open的,所以不需要open
// 2.接口不能有主构造
// 3.实现类不仅仅要重写接口的函数,也要重写接口的成员
// 4.接口实现代码区域要加Override来修饰
fun main() {}
  • 接口的默认实现(只是有这个功能,很少使用)
package com.example.myapplication.kotlinlearn06interface IUSB2 {val usbVersionInfo: Stringget() = "你好小白" //接口的默认实现
}class Mouse2 : IUSB2 {override val usbVersionInfo: Stringget() = super.usbVersionInfo
}// TODO 接口的默认实现
fun main() {val iusb: IUSB2 = Mouse2()println(iusb.usbVersionInfo)}
  • Kotlin的抽象类
package com.example.myapplication.kotlinlearn06abstract class BaseActivity {fun onCreate() {setContentView(getLayoutID())initView()initData()initXXX()}private fun setContentView(layoutID: Int) = println("你好啦啦啦")abstract fun getLayoutID(): Intabstract fun initView()abstract fun initData()abstract fun initXXX()}class MainActivity : BaseActivity() {override fun getLayoutID(): Int {return 1223}override fun initView() {}override fun initData() {}override fun initXXX() {}fun show() = super.onCreate()}//TODO 101-Kotlin的抽象类详解
fun main() = MainActivity().show()
  • 泛型类讲解
package com.example.myapplication.kotlinlearn06abstract class BaseActivity {fun onCreate() {setContentView(getLayoutID())initView()initData()initXXX()}private fun setContentView(layoutID: Int) = println("你好啦啦啦")abstract fun getLayoutID(): Intabstract fun initView()abstract fun initData()abstract fun initXXX()}class MainActivity : BaseActivity() {override fun getLayoutID(): Int {return 1223}override fun initView() {}override fun initData() {}override fun initXXX() {}fun show() = super.onCreate()}//TODO 101-Kotlin的抽象类详解
fun main() = MainActivity().show()
  • 内置函数+泛型
package com.example.myapplication.kotlinlearn06class kt103<T>(private val isR: Boolean, private val obj: T) {fun getObj(): T? = obj.takeIf { isR }
}//TODO 103.内置函数+泛型
fun main() {val s1 = Student("张三", 33)println(kt103(true, s1).getObj())println(kt103(false, s1).getObj())kt103(true, s1).getObj().apply {println(this)}!!
}
  • Kotlin泛型变换实战
package com.example.myapplication.kotlinlearn06class kt104<T>(val isMap: Boolean, val inputType: T) {//false,返回null//true ,返回调用者本身inline fun <R> map(mapAction: (T) -> R): R? = mapAction(inputType).takeIf { isMap }
}//TODO 104.Kotlin的泛型变换实战;’fun main() {val p1: kt104<Int> = kt104(isMap = true, inputType = 333)val r: String? = p1.map {"aaa"}println("变换后的结果是$r")
}
  • kotlin泛型类的约束
    T:Person 这样写的话只有Person 以及Person的子类才可以传进去。

  • Kotlin抽象类

package com.example.myapplication.kotlinlearn06abstract class BaseActivity {fun onCreate() {setContentView(getLayoutID())initView()initData()initXXX()}private fun setContentView(layoutID: Int) = println("你好啦啦啦")abstract fun getLayoutID(): Intabstract fun initView()abstract fun initData()abstract fun initXXX()}class MainActivity : BaseActivity() {override fun getLayoutID(): Int {return 1223}override fun initView() {}override fun initData() {}override fun initXXX() {}fun show() = super.onCreate()}//TODO 101-Kotlin的抽象类详解
fun main() = MainActivity().show()
  • kotlin中vararg关键字
package com.example.myapplication.kotlinlearn06class kt106<T>(vararg objects: T, var isMap: Boolean) {//out 我们的T只能被读取,不能被修改private val objectArray: Array<out T> = objectsfun showObj(index: Int): T? = objectArray[index].takeIf { isMap }
}//TODO 106.kotlin的vararg关键字(动态参数)
fun main() {val p = kt106("aaa", "ddd", isMap = true)println(p.showObj(0))println(p.showObj(1))println(p.showObj(2))
}
  • Kotlin的[]操作符
package com.example.myapplication.kotlinlearn06class kt107<T>(vararg objects: T, var isMap: Boolean) {//out 我们的T只能被读取,不能被修改private val objectArray: Array<out T> = objectsfun showObj(index: Int): T? = objectArray[index].takeIf { isMap }//运算符重载operator fun get(index: Int): T? = objectArray[index].takeIf { isMap }
}//TODO 107.Kotlin的[]操作符讲解
fun main() {val p = kt107("aaa", "ddd", isMap = true)p[0]println(p[1])
}

6.1协变 逆变

  • 协变讲解
package com.example.myapplication.kotlinlearn06interface Producer<out T> {//out T 代表此泛型在整个生产者里边 这个T只能被读取,不能被修改了fun getT(): T}interface Consumer<in T> {//消费者 ,只能修改 不能被读取fun consumer(item: T) //只能被修改}//TODO 108.协变讲解-KT
fun main() {//TODO 协变  相当于Java里的? extends Person  这样保证了只能接受 Person以及Person的子类}
  • 协变讲解
package com.example.myapplication.kotlinlearn06interface Producer<out T> {//out T 代表此泛型在整个生产者里边 这个T只能被读取,不能被修改了fun getT(): T}interface Consumer<in T> {//消费者 ,只能修改 不能被读取fun consumer(item: T) //只能被修改}//TODO 108.协变讲解-KT
fun main() {//TODO 协变  相当于Java里的? extends Person  这样保证了只能接受 Person以及Person的子类//  协变 可以在使用处协变 也可以在生命处协变【Java只有在使用处协变】// 逆变  子类去接收父类 in T 相当于Java 里的 ? super Person 这样保证了 能接收Person以及 Person的父类// 总结: 协变:out 父类 = 子类//   逆变: in  子类=父类
}
  • Kotlin中使用in 和out
package com.example.myapplication.kotlinlearn06class kt110 {
}// 小结,当我们对整个类里边的泛型,只能修改,不能读取时,可以声明为逆变
//  当我们对泛型,只能读取,不能给外界修改更新时,可以声明为协变
class SetClass<out T>(item: T) { //声明式逆变泛型,Java不能在声明处,只能在使用处// 200个函数,对T只能修改,不能对外界读取val res = itemfun get(): T {return res}}// TODO 110-Kotlin中使用in和out
fun main() {val list: List<Int> //不可变val list2: MutableList<Int> //可变集合}
  • reified关键字 监测 泛型T的类型
package com.example.myapplication.kotlinlearn06class Object1inline fun <reified T> showTypeInfo(item: T) {if (Object1() is T) {println("aa")} else if (item is Object1) {}val list = listOf("aa", "bb")list.shuffled().first()//随机获取集合中的元素}class kt111 {
}//TODO reified 是真泛型类型的监测
fun main() {}
  • Kotlin 的 扩展函数
package com.example.myapplication.kotlinlearn06class Object1inline fun <reified T> showTypeInfo(item: T) {if (Object1() is T) {println("aa")} else if (item is Object1) {}val list = listOf("aa", "bb")list.shuffled().first()//随机获取集合中的元素}class kt111 {
}//TODO reified 是真泛型类型的监测
fun main() {}
  • 超类上定义扩展函数
package com.example.myapplication.kotlinlearn06private fun Any.showPrintlnContent() = println("当前的内容是$this") //将方法私有化,this永远是调用者本身//TODO kt113-超类上定义扩展函数
fun main() {true.showPrintlnContent()
}
  • Kotlin泛型的扩展函数
package com.example.myapplication.kotlinlearn06//TODO 114.Kotlin的泛型扩展函数
fun <T> T.showContentInfo() =println("${if (this is String) "你的字符串长度是$length" else "你不是字符串,你的内容是$this"}")fun main() {"许远志".showContentInfo()true.showContentInfo()
}
  • Kotlin的标准函数与泛型扩展函数
package com.example.myapplication.kotlinlearn06//TODO 115.Kotlin的标准函数与泛型扩展函数fun main() {"string".mLet {true"aa"}
}private inline fun <I, O> I.mLet(lambda: (I) -> O): O = lambda(this)
  • Kotlin的内置函数与扩展属性
package com.example.myapplication.kotlinlearn06class kt116//扩展属性
val String.myInfo: Stringget() = "许远志"fun String.showPrintln(): String {println("aaa")return this
}//TODO 116.Kotlin内置函数与扩展属性
fun main() {// run 和let会根据最后一行的返回值作为返回值// run 持有this let 持有it//TODO 扩展属性println("this".myInfo)"333".showPrintln().myInfo}
  • Kotlin可空类型扩展函数
package com.example.myapplication.kotlinlearn06class kt116//扩展属性
val String.myInfo: Stringget() = "许远志"fun String.showPrintln(): String {println("aaa")return this
}//TODO 116.Kotlin内置函数与扩展属性
fun main() {// run 和let会根据最后一行的返回值作为返回值// run 持有this let 持有it//TODO 扩展属性println("this".myInfo)"333".showPrintln().myInfo}
  • infix中缀表达式
package com.example.myapplication.kotlinlearn06//TODO 118.Kotlin的infix关键字
//自定义的中级表达式+扩展函数一起使用
// infix  中缀表达式是简化我们的代码
private infix fun <C1, C2> C1.go(c2: C2) {}fun main() {123.go("许远志")123 go "许远志"
}
  • 导入扩展文件
package com.example.myapplication.kotlinlearn06
//导入扩展文件
import com.example.myapplication.kotlinlearn06.randomItemValue//TODO 119.Kotlin的定义扩展文件fun main() {val list: List<String> = listOf("张三", "李四", "王五")//第一种不使用扩展文件println(list.shuffled().first())println(list.randomItemValue())}
package com.example.myapplication.kotlinlearn06fun <E> Iterable<E>.randomItemValue() = shuffled().first()
  • 重命名扩展函数
package com.example.myapplication.kotlinlearn06//导入扩展文件
import com.example.myapplication.kotlinlearn06.randomItemValue as p//TODO 119.Kotlin的定义扩展文件fun main() {val list: List<String> = listOf("张三", "李四", "王五")//第一种不使用扩展文件println(list.shuffled().first())println(list.p())}

7. 手写内置函数

  • 手写apply函数
package com.example.myapplication.kotlinlearn06class kt121 {}fun main() {"许远志".mApply {"aaa"}.apply { }
}/*private 表示私有inline 因为我们的函数是高阶函数,需要使用内联对lambda进行优化处理fun<INPUT> 函数中声明一个泛型INPUT.mApply 表示所有的类型都能调用这个函数,INPUT.()代表对这个泛型进行了匿名函数扩展 ,函数扩展持有的this,this持有的调用者本身Unit 永远返回调用者本身lambda(this)  永远都有this  ,this可以省略*/
private inline fun <INPUT> INPUT.mApply(lambda: INPUT.() -> Unit): INPUT {lambda()return this;
}
  • DSL学习
package com.example.myapplication.kotlinlearn06import java.io.File//TODO 122.Kotlin的DSL学习
// TODO dsl学习  就是领域专用语言(Domain  Specified Language/DSL)  Gradle,Json,XML等inline fun File.applyFile(action: (String, String) -> Unit): File {action(name, this.name)return this
}fun main() {}
  • Kotlin的map变换函数
package com.example.myapplication.kotlinlearn06class kt123 {
}//TODO 123.Kotlin的map变换函数
fun main() {var list: MutableList<String> = mutableListOf("张三", "李四", "王五")//原理:及时吧匿名函数最后一个返回值加入到新的集合里面去,var list2 = list.map {//it 等于 每一个元素 ”张三" "李四" "王五""it 是$it""$it"}.map {"$ it的长度是${it.length}"}println(list2)
}
  • 变换函数flatmap
package com.example.myapplication.kotlinlearn06class kt124 {
}//TODO 124.Kotlin的变换函数flatMap
fun main() {val list: List<String> = mutableListOf("张三", "李四", "王五")val list2 = list.flatMap { //每次都会返回一个集合 ,把买一个集合加到新集合里listOf("aaa", "bbb", "ccc")  //会做扁平化处理 ,把每个元素变成一个新的集合,然后又加入到新的集合去}val list3 = list.map {"赵六"}println(list2)println(list3)
}
  • 过滤函数filter
package com.example.myapplication.kotlinlearn06class kt125 {
}//TODO 125.过滤函数 filter
fun main() {val names = listOf("张三", "李四", "王五")val result = names.filter {it == "张三"   //如果为true 会加入到新的集合 如果为false 则过滤掉}names.filter {it.contains('张')}.map {println("$it")}println(result) //新集合 把过滤后的元素加入新集合
}
  • 合并函数zip
package com.example.myapplication.kotlinlearn06class kt126 {
}//TODO 126.Kotlin的合并函数zip
fun main() {val names = listOf("张三", "李四", "王五")val ages = listOf(1, 2, 3)val zip: List<Pair<String, Int>> = names.zip(ages)println(zip.toMap())println(zip)//遍历zip.forEach {//println("姓名是${it.first},年龄是${it.second}")}//解构zip.toMap().forEach { (k, v) ->println("k是$k,v是$v")}
}
  • 函数式编程(响应式编程)
package com.example.myapplication.kotlinlearn06class kt126 {
}//TODO 126.Kotlin的合并函数zip
fun main() {val names = listOf("张三", "李四", "王五")val ages = listOf(1, 2, 3)val zip: List<Pair<String, Int>> = names.zip(ages)println(zip.toMap())println(zip)//遍历zip.forEach {//println("姓名是${it.first},年龄是${it.second}")}//解构zip.toMap().forEach { (k, v) ->println("k是$k,v是$v")}
}
  • Kotlin的互操作性和可空性
package com.example.myapplication.kotlinlearn06//TODO 128.Kotlin的互操作性与可空性
fun main() {var name: String? = "a"//接收Java的变量的时候要用string?来接收Java的值name = nullprintln(name?.length)
}

7.1 Kotlin的单例模式

package com.example.myapplication.kotlinlearn06//TODO 单例模式
//1.饿汉式的实现 KT版本   先把实例实例化出来
object Singleton//2. 懒汉式实现
class Singleton2 private constructor() {companion object {private var instance: Singleton2? = nullget() {if (field == null) {field = Singleton2()}return field}fun getInstance(): Singleton2? = instance}
}// 3.线程安全版本
class Singleton3 private constructor() {companion object {private var instance: Singleton3? = nullget() {if (field == null) {field = Singleton3()}return field}@Synchronizedfun getInstance(): Singleton3? = instance}
}//4. 双重校验锁版本
class Singleton4 private constructor() {companion object {val instance: Singleton4 by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) { Singleton4() }}
}

7.2 Kotlin的注解

  • @JvmName
@file:JvmName("Stu") //在编译时把类名改成自定义的名称
package com.example.myapplication.kotlinlearn06class kt130 {
}//TODO 130.注解@jvmName
fun main() {println("hello world")
}
  • JvmField注解
package com.example.myapplication.kotlinlearn06class kt131 {@JvmField //把反编译后的Java代码修饰符变成publicval names = listOf("张三", "李四", "王五")
}// TODO 131.注解@JvmField
fun main() {}
  • JvmStatic注解
package com.example.myapplication.kotlinlearn06class MyObject {companion object {@JvmFieldval TARGET = "张三"@JvmStatic //加上这个注解之后,在Java里使用这个方法就可以直接用了,fun showAction(name: String) = println("$name 要去 $TARGET 玩")}
}//TODO 133.注解@JvmStatic与Kotlin的关系
fun main() {//KT 端println(MyObject.TARGET)MyObject.showAction("啦啦啦")
}

7.3 手写RxJava

package com.example.myapplication.kotlinlearn06class kt134 {
}// TODO 134.手写RxJava操作符
//  Lambda是以最后一行作为返回值
fun main() {create {"333"}.map {"张三"true"ddd"}.map {}
}class RxJavaCoreClassObject<T>(val valueItem: T)inline fun <INPUT, OUTPUT> RxJavaCoreClassObject<INPUT>.map(mapAction: INPUT.() -> OUTPUT): RxJavaCoreClassObject<OUTPUT> {val mapResult = valueItem.mapAction()return RxJavaCoreClassObject(mapResult)
}//create 接收一个lambda表达式作为参数,然后执行lambda的函数体,然后等create参数调用
inline fun <CREATE_OUTPUT> create(createLambda: () -> CREATE_OUTPUT): RxJavaCoreClassObject<CREATE_OUTPUT> {val createResult: CREATE_OUTPUT = createLambda()return RxJavaCoreClassObject(createResult)
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/820745.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

全球顶级的低代码开发平台,你知道几个?

什么是低代码开发平台? 低码开发平台是一个应用程序,提供图形用户界面编程,从而以非常快的速度开发代码,减少了传统的编程工作。 这些工具有助于快速开发代码,最大限度地减少手工编码的努力。这些平台不仅有助于编码,而且还能快速安装和部署。 低码开发工具的好处 低代码平…

为什么公共云的弹性能力很难被发挥出来?

作者&#xff5c;王小瑞 AutoMQ 联合创始人 & CEO 云计算通过资源池化实现单位资源成本更优&#xff0c;使企业能够将 IDC 建设、基础软件研发和运维等工作外包给云厂商&#xff0c;从而更专注于业务创新。资源池不仅包括服务器&#xff0c;还包括人才。云厂商集聚了优秀…

ubuntu20.04.3挂载共享文件夹

VMware设置win共享文件夹 在linux执行挂载命令 sudo vmhgfs-fuse /mnt/hgfs/ -o nonempty这样就可以用管理员访问/mnt/hgfs/share

Java全套智慧校园系统源码springboot+elmentui +Quartz可视化校园管理平台系统源码 建设智慧校园的5大关键技术

Java全套智慧校园系统源码springbootelmentui Quartz可视化校园管理平台系统源码 建设智慧校园的5大关键技术 智慧校园指的是以物联网为基础的智慧化的校园工作、学习和生活一体化环境&#xff0c;这个一体化环境以各种应用服务系统为载体&#xff0c;将教学、科研、管理和校园…

Docker仅需3步搭建免费私有化的AI搜索引擎-FreeAskInternet

简介 FreeAskInternet 是一个完全免费、私有且本地运行的搜索引擎&#xff0c;并使用 LLM 生成答案&#xff0c;无需 GPU。用户可以提出问题&#xff0c;系统会进行多引擎搜索&#xff0c;并将搜索结果合并到ChatGPT3.5 LLM中&#xff0c;并根据搜索结果生成答案。 什么是 Fr…

3D视觉引导麻袋拆垛破包 | 某大型化工厂

客户需求 此项目为大型化工厂&#xff0c;客户现场每日有大量麻袋拆垛破包需求&#xff0c;麻袋软包由于自身易变形、码放垛型不规则、运输后松散等情况&#xff0c;无法依靠机器人示教位置完成拆垛。客户遂引入3D视觉进行自动化改造。 工作流程&#xff1a; 3D视觉对紧密贴合…

《剑指 Offer》专项突破版 - 面试题 107 : 矩阵中的距离(C++ 实现)

题目链接&#xff1a;矩阵中的距离 题目&#xff1a; 输入一个由 0、1 组成的矩阵 M&#xff0c;请输出一个大小相同的矩阵 D&#xff0c;矩阵 D 中的每个格子是矩阵 M 中对应格子离最近的 0 的距离。水平或竖直方向相邻的两个格子的距离为 1。假设矩阵 M 中至少有一个 0。 …

JavaScript事件监听测试代码

效果图 代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>信息填写页面</title><link …

在STM32中给固定的地址写入一个值,并通过memory窗口进行查看

首先对STM32中存储数据的地方有一个了解 一个是FLASH,一个是RAM RAM是易失存储器&#xff0c;FLASH是非易失存储器&#xff0c;这是最直观的解释。 主要记住以下几点&#xff1a; RAM&#xff08;随机存储器&#xff09;&#xff1a;既可以从中读取数据&#xff0c;也可以写…

GitHub repository - commits - branches - releases - contributors

GitHub repository - commits - branches - releases - contributors 1. commits2. branches3. releases4. contributorsReferences 1. commits 在这里可以查看当前分支的提交历史。左侧的数字表示提交数。 2. branches 可以查看仓库的分支列表。左侧的数字表示当前拥有的分…

AppBuilder升级!工作流编排正式上线!AssistantsAPI开放邀测!

>>【v0.5.3版本】 上线时间&#xff1a;2024/4/14 关键发版信息&#xff1a; 低代码态&#xff1a;新增工作流&#xff0c;低代码制作组件 自定义组件&#xff1a;支持用户自定义创建组件&#xff0c;并被Agent自动编排调用
 工作流框架&#xff1a;组件支持流式编排…

全视通智慧门诊方案助力满洲里市人民医院实现“医”路畅通

近年来&#xff0c;国家有关部门出台多项政策&#xff0c;意在进一步优化医疗服务&#xff0c;提升患者体验&#xff0c;不断满足人民群众日益增长的美好生活需要。 2019年&#xff0c;《医院智慧服务分级评估标准体系&#xff08;试行&#xff09;&#xff08;2019版&#xf…

DataGrip数据库管理工具安装使用

DataGrip数据库管理工具安装使用 DataGrip介绍 DataGrip是jetbrains旗下的一款数据库管理工具&#xff0c;相信做过java开发的同学都知道&#xff0c;idea就是这家公司发明的。 DataGrip 是JetBrains公司开发的数据库管理客户端工具&#xff08;操作数据库的IDE&#xff0c;…

Meta新一代AI芯片亮相

作为其对人工智能应用投资的一部分&#xff0c;Meta去年还开发了一种定制芯片——Meta Training and Inference Accelerator&#xff0c;或MTIA&#xff0c;用于其数据中心在其流行平台上运行人工智能产品&#xff0c;包括Facebook、Instagram和WhatsApp&#xff0c;并训练其人…

C语言练习:变种水仙花数

今天让我们来看看变种的水仙花吧&#xff0c;话不多说&#xff0c;直入主题。 题目描述 变种水仙花数- Lily Number: 把任意的数字&#xff0c;从中间拆分成两个数字&#xff0c;比如1461可 以拆分成(1和461)&#xff0c;(14和61)&#xff0c;(146和1),如果所有拆分后的乘积之和…

硬盘当前用户无权限、主机名修改...

将文件夹的权限从root变更为当前用户 su rootchown -R admin1 /media/admin1/hdd1/media/admin1/hdd1为硬盘挂载目录 在 Linux 中使用 /etc/hostname 来更改主机名 除了上面的方法外&#xff0c;我们还可以通过修改 /etc/hostname 文件来达到修改主机名的目的。但这个方法需…

企业管理员工微信必备

在微信私域管理系统后台&#xff0c;管理员可以对销售工作微信进行实时监管&#xff0c;以确保业务员的微信使用符合工作要求&#xff0c;并避免资源的浪费。通过监管业务员在手机端微信的一举一动&#xff0c;包括发送会话的次数、接收消息的次数、添加好友的数据等&#xff0…

芯片低功耗VCLP

​VCLP&#xff08;VC Low Power&#xff09;是Synopsys提供的一款低功耗静态规则检查工具&#xff0c;它能够帮助验证和清洁IEEE 1801 Unified Power Format (UPF)低功耗设计意图&#xff0c;并确保UPF中的功耗意图与实现一致。VCLP通过执行语法和语义检查&#xff0c;有助于在…

【重装系统】分配D盘

1.右键“此电脑”&#xff0c;点击管理 2.选择“存储”–磁盘管理 3.右键未分配磁盘–新建简单卷 4.一路默认设置即可

企业网站建设需要了解什么

在现代商业环境中&#xff0c;企业网站已经成为企业宣传、推广和销售的重要工具。企业网站的建设需要考虑多个因素&#xff0c;包括以下几个方面&#xff1a; 首先&#xff0c;了解企业的目标和定位。企业网站的建设应该围绕企业的目标和定位展开&#xff0c;以达到企业在市场中…