kotlin基础1

本文详细介绍了Kotlin与Java在函数、空安全、类型推断、变量声明、数据类型、函数引用等方面的差异,强调了Kotlin的空安全机制、类型系统、函数表达式和内置函数的使用,以及其在处理集合和异常处理上的灵活性。通过实例展示了Kotlin如何简化代码并提高安全性,揭示了Kotlin语言的独特魅力。
摘要由CSDN通过智能技术生成

kotlin与java的区别

(1)java的函数先有输出,再有输入

(2)kotlin的函数先有输入,再有输出 

1、kotlin的空检测机制

var name:String ?= null

(1) name?.length   name如果真的是null后面的不执行,就不会引发空指针异常

(2) name!!.length  无论name是否为null,后面的都会执行,和java一样

(3)if(name!=null) name.length  同java

2、val 与 var 类型推断

(1)val 可读不可改 ,不能再重新赋值

val name:String ="zhangsan"
println("name:$name")

(2)var 可读可改

var sex:Char = 'M'

sex= 'A'

println("sex:$sex")

(3)val与var使用场景

尽量使用val,如果后续此变量需要更改,就使用var

(4)类型推断,推断出name为字符串类型

val name="dany"

3、函数

//隐士的Unit等价于java中的void
fun save():Unit{
}

//等同于
fun save(){
}

//有参数的,number1和number2为形参

fun add(number1:Int,number2:Int):Int{
    return number1+number2
}

//一行简写方式,等用于如上

fun add(number1:Int,number2:Int):Int = number1+number2

//类型推导,返回值为int

fun method()= 100

4、内置数据类型

String  字符串

Char 单字符

Boolean  true/false

Int 整型

Double 小数

List集合

Set 无重复的元素集合

Map 键值对的集合

Int ------->转换成java的int

Float ---------------->转换成java的float

5、Kotlin的编译时常量

编译时常量只能是常用的基本数据类型:String , Double , Int , Float , Long ,Short , Byte , Char  , Boolean

const val PI = 3.1415926 //定义编译时常量

注意:修饰符const 不适用于局部变量,只能在函数之外定义,就可以在编译期间初始化了

val info = "info" //只读类型的变量

6、返回值类型

Unit  相当于java中的void

Any 相当于java中的Object

Int Double 引用类型 = 反编译后= KT  int  double

Double? =反编译后 = Double

函数声明   

java:  public void method1()

kotlin: var method:() -> Unit

函数声明实现结合

java:  public void method1(){}

kotlin: var method={ printlin("aaaaaaaaaa")}

7、kotlin的range表达式

val score = 98
fun getScore() {
        if (score in 0..59) {
            LogUtil.d("不及格")
        } else if (score in 60..79) {
            LogUtil.d("中等")
        } else if (score in 80..100) {
            LogUtil.d("优秀")
        } else if (score !in 0..100) {
            LogUtil.d("不在0-100范围内")
        }
    }

8、kotlin的when表达式

val week = 6
val content = when (week) {
            1 -> "星期一"
            2 -> "星期二"
            3 -> "星期三"
            4 -> "星期四"
            5 -> "星期五"
            6 -> "星期六"
            7 -> "星期日"
            else -> {
                LogUtil.d("其他")
            }
        }

9、kotlin的String模板

(1)$变量名 空格(后面不接字符串)

(2)${变量名}(后面可接字符串)

val content = "aaa"
val time = 6;
LogUtil.d("打印:${content}哈哈,去了$time 次")
//KT的if是表达式,所以更灵活 java的if是语句还有局限性
var isLogin = true
LogUtil.d("${if (isLogin) "登录成功了" else "登录失败了" }")

10、kotlin函数中的默认值

 fun getDefaultData(name:String="lisi",age:Int=18){
     LogUtil.d("姓名:$name,年龄:$age")
 }

调用:可以赋值也可以不赋值

getDefaultData()

11、kotlin的具名函数参数

 fun getStuInfo(name: String,age: Int,sex:String,password:String,info:String){
        LogUtil.d("姓名:$name,年龄:$age")
    }

调用:

 getStuInfo(age = 10,password = "123456",sex = "男",name = "哈哈",info = "111")

12、kotlin的Nothing类型特点

 fun show(score: Int) {
        when (score) {
            in 0..59 -> LogUtil.d("不及格")
            in 60..79 -> LogUtil.d("及格")
            in 80..100 -> LogUtil.d("优秀")
            -1 -> TODO("没有这种分数")  //结束当前程序
        }
    }

13、kotlin的反引号中函数名特点   esc键下面的键

is/in在kt里面就是关键字,怎么办呢,使用反引号 

MainActivity.`in()`

14、kotlin的匿名函数

val num = "marry".count()   //5


val count = "marry".count{
       it.equal("r")
}

//有几个r字符串,2个

15、Kotlin的函数类型&隐式返回学习

// 第一步:函数输入输出的声明
    val methodAction : () -> String

    // 第二步:对上面函数的实现
    methodAction = {
        val inputValue = 999999
        "$inputValue marry" // == 背后隐式 return "$inputValue marry";
        // 匿名函数不要写return,最后一行就是返回值
    }

    // 第三步:调用此函数
    println(methodAction())

16、Kotlin的函数参数

// 第一步:函数输入输出的声明   第二步:对声明函数的实现
    val methodAction : (Int, Int, Int) -> String = { number1, number2, number3 ->
        val inputValue = 999999
        "$inputValue hh 参数一:$number1, 参数二:$number2, 参数三:$number3"
    }
    // 第三步:调用此函数
    println(methodAction(1, 2, 3))

17、Kotlin的it关键字特点

//一个参数时,隐式参数为it
val methodAction2 : (String) -> String = { "$it hh" }
println(methodAction2("DDD"))

18、Kotlin的lambda学习

// 匿名函数 == lambda表达式
    val addResultMethod = { number1 : Int, number2: Int ->
        "两数相加的结果是:${number1 + number2}"
    } // addResultMethod 函数: (Int, Int) -> String
    println(addResultMethod(1, 1))

    // 匿名函数 入参 Int,          返回 Any类型
    // lambda表达式的参数 Int,    lambda表达式的结果Any类型
    val weekResultMethod = { number: Int ->
        when(number) {
            1 -> "星期1"
            2 -> "星期2"
            3 -> "星期3"
            4 -> "星期4"
            5 -> "星期5"
            else -> -1
        }
    } // weekResultMethod 函数: (Int) -> Any
    println(weekResultMethod(2))

    // 匿名函数 属于 lambda

19、在函数中定义参数是函数的函数  及函数内联

fun main() {
    loginAPI("hh", "123456") { msg: String, code: Int ->
        println("最终登录的情况如下: msg:$msg, code:$code")
    }
}

// 模拟:数据库SQLServer
const val USER_NAME_SAVE_DB = "hh"
const val USER_PWD_SAVE_DB = "123456"

// 此函数有使用lambda作为参数,就需要声明成内联
// 如果此函数,不使用内联,在调用端,会生成多个对象来完成lambda的调用(会造成性能损耗)
// 如果此函数,使用内联,相当于 C++ #define 宏定义 宏替换,会把代码替换到调用处,调用处 没有任何函数开辟 对象开辟 的损耗
// 小结:如果函数参数有lambda,尽量使用 inline关键字,这样内部会做优化,减少 函数开辟 对象开辟 的损耗
// 登录API 模仿 前端
//responseResult: (String, Int) -> Unit相当于java中的自定义接口
public inline fun loginAPI(username: String, userpwd: String, responseResult: (String, Int) -> Unit) {
    if (username == null || userpwd == null) {
        TODO("用户名或密码为null") // 出现问题,终止程序
    }

    // 做很多的校验 前端校验
    if (username.length > 3 && userpwd.length > 3) {
        if (wbeServiceLoginAPI(username, userpwd)) {
            // 登录成功
            // 做很多的事情 校验成功信息等
            // ...
            responseResult("login success", 200)
        } else {
            // 登录失败
            // 做很多的事情 登录失败的逻辑处理
            // ...
            responseResult("login error", 444)
        }
    } else {
        TODO("用户名和密码不合格") // 出现问题,终止程序
    }
}

// 此函数没有使用lambda作为参数,就不需要声明成内联
// 登录的API暴露者 服务器
private fun wbeServiceLoginAPI(name: String, pwd: String) : Boolean {
    // kt的if是表达式(很灵活)     java的if是语句(有局限性)

    // 做很多的事情 登录逻辑处理
    // ...

    return if (name == USER_NAME_SAVE_DB && pwd == USER_PWD_SAVE_DB) true else false
}

20、Kotlin的函数引用学习 

::函数名

fun main() {
    // 函数引用
    // lambda属于函数类型的对象,需要把methodResponseResult普通函数变成 函数类型的对象(函数引用)

    // login("hh", "123456", ::methodResponseResult)

    val obj = ::methodResponseResult
    val obj2 = obj
    val obj3 =  obj2

    login("hh", "123456", obj3)
}

fun methodResponseResult(msg: String, code: Int) {
    println("最终登录的成果是:msg:$msg, code:$code")
}


// 模拟:数据库SQLServer
const val USER_NAME_SAVE_DB4 = "hh"
const val USER_PWD_SAVE_DB4= "123456"

inline fun login(name: String, pwd: String, responseResult: (String, Int) -> Unit) {
    if (USER_NAME_SAVE_DB4 == name && USER_PWD_SAVE_DB4 == pwd) {
        // 登录成功
        // 做很多的事情 校验成功信息等
        responseResult("登录成功", 200)
        // ...
    } else {
        // 登录失败
        // 做很多的事情 登录失败的逻辑处理
        // ...
        responseResult("登录失败错了", 444)
    }
}

21、Kotlin的函数类型作为返回类型 

fun main() {
    val r = show("学习KT语言")
    // r 是show函数的 返回值

    val niming_showMethod = showMethod("show")
    // niming_showMethod 是 showMethod函数的返回值 只不过这个返回值 是一个 函数

    // niming_showMethod == 匿名函数
    println(niming_showMethod("hh",18))
}

fun show(info: String): Boolean {
    println("我是show函数 info:$info")
    return true
}

fun show2(info: String): String {
    println("我是show函数 info:$info")
    return "DDD"
}

fun show3(info: String): String {
    println("我是show函数 info:$info")
    return /*888*/ ""
}

// showMethod函数 再返回一个 匿名函数
fun showMethod(info: String): (String, Int) -> String {
    println("我是show函数 info:$info")

    // return 一个函数 匿名函数
    return { name: String, age: Int ->
        "我就是匿名函数:我的name:$name, age:$age"
    }
}

22、Kotlin的匿名函数与具名函数

fun main() {

    // 匿名函数
    showPersonInfo("lisi", 99, '男', "学习KT语言") {
        println("显示结果:$it")
    }

    // 具名函数 showResultImpl
    showPersonInfo("wangwu", 89, '女', "学习C++语言", ::showResultImpl)

}

fun showResultImpl(result: String) {
    println("显示结果:$result")
}

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)
}

23、Kotlin的可空性特点

// TODO 第一种情况:默认是不可空类型,不能随意给null
    var name: String = "hh"

    // 提示:不能是非空类型String的值
    // name = null

    println(name)

    // TODO 第二种情况:声明时指定为可空类型
    var name2: String ?=null
    // name2 = "hh"
    println(name2)

24、Kotlin的安全调用操作符

fun main() {
    var name: String? = "zhangsan"
    // name = null

    // name.capitalize() // name是可空类型的 可能是null,想要使用name,必须给出补救措施

    val r = name?.capitalize() // name是可空类型的 如果真的是null,?后面这一段代码不执行,就不会引发空指针异常
    println(r)
}

25、在Kotlin中使用带let的安全调用

fun main() {
    var name: String? = null
    name = "Derry"
    name = ""

    // name是可空类型的 如果真的是null,?后面这一段代码不执行,就不会引发空指针异常
    val r =name?.let {
        // it == name 本身
        // 如果能够执行到这里面的,it 一定不为null

        if (it.isBlank()) { // 如果name是空值 "" 没有内容
            "Default"
        } else {
            "[$it]"
        }
    }
    println(r)
}

26、Kotlin中的非空断言操作符特点

fun main() {
   var name: String? = null

    // name.capitalize() // name是可空类型的 可能是null,想要使用name,必须给出补救措施

    // name = "hh"
    // 补救措施  我们已经学习了 ?
    val r = name!!.capitalize() // !! 断言 不管name是不是null,都执行,这个和java一样了
    println(r)

    // 结论:规矩:如果百分百能够保证name是有值的,那么才能使用断言 !!, 否则有Java 空指针异常的风险
}

27、Kotlin语法中对比使用if判断null值情况

fun main() {
    var name: String? = null
    name = "hh"

    // name.capitalize() // name是可空类型的 可能是null,想要使用name,必须给出补救措施

    if (name != null) { // if也算是补救措施,和Java一样了
        val r = name.capitalize()
        println(r)
    } else {
        println("name is null")
    }
}

28、在Kotlin空合并操作符 ?:

fun main() {
    var info: String? = "张三"
    // info = null

    // 空合并操作符  xxx ?: "原来你是null啊"    "如果xxx等于null,就会执行 ?: 后面的区域"
    println( info ?: "原来你是null啊" )


    // let函数 + 空合并操作符
    println(info?.let { "【$it】" } ?: "原来你是null啊2")
}

29、在Kotlin语法中异常处理与自定义异常特点

fun main() {
   try {
       var info: String? = null

       checkException(info)

       println(info!!.length)

   }catch (e: Exception) {
       println("啊呀:$e")
   }
}

fun checkException(info: String?) {
   info ?: throw CustomException()
}

class CustomException : IllegalArgumentException("你的代码太不严谨了")

30、Kotlin的先决条件函数

fun main() {
    var value1: String ? = null
    var value2: Boolean = false

    // checkNotNull(value1) // java.lang.IllegalStateException: Required value was null.

    // requireNotNull(value1) // java.lang.IllegalArgumentException: Required value was null.

    require(value2) // java.lang.IllegalArgumentException: Failed requirement.
}

31、Kotlin的substring

fun main() {
    val indexOf = INFO.indexOf('i')
    println(INFO.substring(0, indexOf))
    println(INFO.substring(0 until indexOf)) // KT基本上用此方式: 0 until indexOf
}

32、Kotlin的split操作

//kotlin解构指的是将对象的多个属性分别赋值给多个变量的过程

了解解构

fun main() {
    val jsonText = "dong,nan,xi,bei"
    // list 自动类型推断成 list == List<String>
    val list = jsonText.split(",")

    // 直接输出 list 集合,不解构
    println("分割后的list里面的元素有:$list")

    // C++ 解构  Kt也有解构
    val (v1, v2, v3, v4) = list
    println("解构四个只读变量的值是:v1:$v1, v2:$v2, v3:$v3, v4:$v4")
}

33、Kotlin的replace完成加密解码操作

fun main() {
   val sourcePwd = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    println("原始密码是:$sourcePwd")

    // 加密操作:就是把字符替换成数字 打乱了,就属于加密了
    val newPwd = sourcePwd.replace(Regex("[AKMNO]")) {
        it.value // 完全没有做任何事情

        when(it.value) { // 这里的每一个字符 A B C D ...
            "A" -> "9"
            "K" -> "3"
            "M" -> "5"
            "N" -> "1"
            "O" -> "4"
            else -> it.value // 就啥事不做,直接返回 字符本身 A B C D ...
        }
    }
    println("加密后的密码是:$newPwd")

    // 解密操作
    val sourcePwdNew = newPwd.replace(Regex("[9514]")) {
        when(it.value) {
            "9" -> "A"
            "3" -> "K"
            "5" -> "M"
            "1" -> "N"
            "4" -> "O"
            else -> it.value // 就啥事不做,直接返回 字符本身 A B C D ...
        }
    }
    println("解密后的密码是:$sourcePwdNew")
}

34、Kotlin的==与===比较操作

fun main() {
    // == 值 内容的比较  相当于Java的equals
    // === 引用的比较

    val name1 : String = "Merry"
    val name2 : String = "Merry"
    val name3 = "ww"

    // 小结:name1.equals(name2)  等价于 name1 == name2  都是属于 值 内容的比较
    println(name1.equals(name2)) // java
    println(name1 == name2) // kt

    // 引用的比较
    println(name1 === name2) // true
    println(name1 === name3) // false

    // 引用的比较 难度高一点点
    val name4 = "merry".capitalize() // 修改成"Merry"
    println(name4 === name1)
}

35、Kotlin的字符串遍历操作

fun main() {
    val str = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    str.forEach {  c -> // 覆盖默认的it参数名,修改参数名为 c
        // it == str的每一个字符 A B C D ...
        // print("所有的字符是:$it  ")
        print("所有的字符是:$c  ")
    }
}

36、Kotlin中数字类型的安全转换函数

fun main() {
    val number: Int = "666".toInt()
    println(number)

    // 字符串里面放入了Double类型,无法转换成Int,会奔溃
    // val number2: Int = "666.6".toInt()
    // println(number2)

    // 解决上面奔溃的问题
    val number2: Int? = "666.6".toIntOrNull()
    println(number2)

    val number3: Int? = "888".toIntOrNull()
    println(number3)

    val number4: Int? = "888.8".toIntOrNull()
    println(number4 ?: "原来你是null啊")

    // 小结:以后字符串有整形相关的转换,尽量用 toIntOrNull 此函数
}

37、Kotlin中Double转Int与类型格式化

fun main() {
    println(65.4645654.toInt()) // 65 四舍五入

    println(65.4645654.roundToInt())  // 65 四舍五入

    println(65.8343433.roundToInt()) // 66 四舍五入

    // 结论:用 roundToInt()函数,保证 Double ->转Int 持有四舍五入的效果

    // r的类型: String
    val r  = "%.3f".format(65.8343433)
    println(r)

}

38、Kotlin的apply内置函数

fun main() {
    val info = "Lerry You Hao"

    // 普通的方式
    println("info字符串的长度是:${info.length}")
    println("info最后一个字符是:${info[info.length -1]}")
    println("info全部转成小写是:${info.toLowerCase()}")

    println()

    // apply内置函数的方式
    // info.apply特点:apply函数始终是返回 info本身 String类型
    val infoNew : String = info.apply {
        // 一般大部分情况下,匿名函数,都会持有一个it,但是apply函数不会持有it,却会持有当前this == info本身
        println("apply匿名函数里面打印的:$this")

        println("info字符串的长度是:${length}")
        println("info最后一个字符是:${this[length -1]}")
        println("info全部转成小写是:${toLowerCase()}")
    }
    println("apply返回的值:$infoNew")

    println()

    // 真正使用apply函数的写法规则如下:
    // info.apply特点:apply函数始终是返回 “info本身”,所以可以链式调用
    info.apply {
        println("长度是:$length")
    }.apply {
        println("最后一个字符是:${this[length -1]}")
        true
        true
        true
    }.apply {
        println("全部转成小写是:${toLowerCase()}")
    }

    println()

    // 普通写法
    val file = File("D:\\a.txt")
    file.setExecutable(true)
    file.setReadable(true)
    println(file.readLines())

    println()

    // apply写法
    // 匿名函数里面 持有的this == file本身
    /*val fileNew: File =*/ file.apply {
        setExecutable(true)
    }.apply {
        setReadable(true)
    }.apply {
        println(file.readLines())
    }
}

39、Kotlin的let内置函数

// 普通方式 对集合第一个元素相加
// let方式 对集合第一个元素相加
// 普通方式 对值判null,并返回
// let方式 对值判null,并返回
fun main() {
    // 普通方式 对集合第一个元素相加
    val list = listOf(6, 5, 2, 3, 5, 7)
    val value1 = list.first() // 第一个元素
    val result1 = value1 + value1
    println(result1)

    // let方式 对集合第一个元素相加
    val result2 = listOf(6, 5, 2, 3, 5, 7).let {
        // it == list集合
        it.first() + it.first() // 匿名函数的最后一行,作为返回值,let的特点,   但是前面学的apply永远是返回info本身
        /*true
        true
        true*/
    }
    println(result2)

    println()

    // 普通方式 对值判null,并返回
    println(getMethod1(/*null*/ "Merry"))

    // let方式 + 空合并操作符 对值判null,并返回
    println(getMethod3(/*null*/ "Merry"))
}

// 普通方式 对值判null,并返回
fun getMethod1(value: String?) : String {
    return if (value == null) "你传递的内容是null,你在搞什么飞机" else "欢迎回来${value}非常欢迎"
}
// 普通方式 简化版本
fun getMethod2(value: String?) = if (value == null) "你传递的内容是null,你在搞什么飞机" else "欢迎回来${value}非常欢迎"

// let方式 + 空合并操作符 对值判null,并返回
fun getMethod3(value: String?) : String {
    return value?.let {
        "欢迎回来${it}非常欢迎"
    } ?: "你传递的内容是null,你在搞什么飞机"
}

// let方式 + 空合并操作符 对值判null,并返回 简化版本
fun getMethod4(value: String?) =
     value?.let {
        "欢迎回来${it}非常欢迎"
    } ?: "你传递的内容是null,你在搞什么飞机"

40、Kotlin的run内置函数

// 1.run函数的特点 字符串延时
// 2.具名函数判断长度 isLong
// 3.具名函数监测合格 showText
// 4.具名函数增加一个括号 mapText
// 5.具名函数输出内容
fun main() {
    val str = "Merry is OK"
    val r1 : Float = str.run {
        // this == str本身
        true
        5435.5f
    }
    println(r1)

    // 下面是 具名函数 配合 run函数

    // 2.具名函数判断长度 isLong

    // 这个是属于 匿名函数 配合 run
    str.run {
        // this == str本身
    }

    // 这个是属于具名函数
    // str.run(具名函数)
    str
        .run(::isLong) // this == str本身
        .run(::showText) // this == isLong返回的boolean值
        .run(::mapText)
        .run(::println)

    println()

    // let函数持有it,run函数持有this 都可以很灵活的,把上一个结果值 自动给 下一个函数
    str.let(::isLong) // it == str本身
    .let(::showText) // it == isLong返回的boolean值
    .let(::mapText) // it == str本身
    .let(::println) // it == str本身

    println()

    // >>>>>>>>>>>>>>>>>>>>>> 上面全部都是具名函数调用给run执行  下面全部是 匿名函数调用给run执行
    str
        .run {
            if (length > 5) true else false
        }
        .run {
            if (this) "你的字符串合格" else "你的字符串不合格"
        }
        .run {
            "【$this】"
        }
        .run {
            println(this)
        }
}

fun isLong(str: String) /* : Boolean */ = if (str.length > 5) true else false

fun showText(isLong: Boolean) /*: String */ = if (isLong) "你的字符串合格" else "你的字符串不合格"

fun mapText(getShow: String) /*: String */ = "【$getShow】"

41、Kotlin的with内置函数

fun main() {
    val str = "李元芳"

    // 具名操作
    /*with(str) {
        this == str本身
    }*/
    val r1 = with(str, ::getStrLen)
    val r2 = with(r1, ::getLenInfo)
    val r3 = with(r2, ::getInfoMap)
    with(r3, ::show)

    println()

    // 匿名操作
    with(with(with(with(str) {
        length
    }) {
        "你的字符串长度是:$this"
    }){
        "【$this】"
    }){
        println(this)
    }
}

fun getStrLen(str: String) = str.length
fun getLenInfo(len: Int) = "你的字符串长度是:$len"
fun getInfoMap(info: String) = "【$info】"
fun show(content: String) = println(content)

42、Kotlin的also内置函数 

fun main() {
    val str = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"

    val r1 : String = str.also {
        true
        354543.4f
        454
        'C'
    }

    val r2 : Int = 123.also {
        true
        354543.4f
        454
        'C'
        false
    }

    str.also {
        // it == str本身
    }

    // 真正使用also函数的写法规则如下:
    // str.also特点:also函数始终是返回 “str本身”,所以可以链式调用
    str.also {
        println("str的原始数据是:$it")
    }.also {
        println("str转换小写的效果是:${it.toLowerCase()}")
    }.also {
        println("结束了")
    }

    val file = File("D:\\a.txt")


    // 匿名函数里面做的事情,和sourceFile无关,因为永远都是返回 file本身
    val sourceFile = file.also {
        file.setReadable(true)
        file.setWritable(true)
        println(file.readLines())
        // 假设 做了很多很多的事情
        // ...
    }.also {
        file.setReadable(true)
        println(file.readLines())
        // 假设 做了很多很多的事情
        // ...
    }.also {
        file.setReadable(true)
        println(file.readLines())
        // 假设 做了很多很多的事情
        // ...
    }
    // sourceFile没有任何影响
}

43、内置函数总结(apply/let/run/with)

(1)apply   str.apply { this }

  • apply函数返回类型,永远都是info本身,此条和also一模一样
  • apply函数的匿名函数里面持有的是this==info本身,此条和run一模一样

(2)let   str.let{it}

  • let函数返回类型,是根据匿名函数最后一行的变化而变化,此条和run一模一样
  • let函数的匿名函数里面持有的是it==info本身, 此条和also一模一样

(3)run    str.run{this}

  •  run函数返回类型,是根据匿名函数最后一行的变化而变化,此条和let一模一样
  • run函数的匿名函数里面持有的是this==info本身 ("aa".run{}) ,此条和apply一模一样

  (4)   with     with(str)

  •  run函数返回类型,是根据匿名函数最后一行的变化而变化,此条和let一模一样
  • run函数的匿名函数里面持有的是this==info本身 ("aa".run{}) ,此条和apply一模一样

 (5)str.also{}

  •  also函数返回类型,永远都是info本身   此条和apply一模一样
  •  also函数的匿名函数里面持有的是it==info本身 ("aa".run{}) ,此条和let一模一样

44、Kotlin的takeIf内置函数    str.takeIf{true/false}?: "hh"

一般大部分情况下,都是 takeIf + 空合并操作符 = 一起使用

fun main() {
    val result = checkPermissionAction("Root2", "!@#$")
    // println("欢迎${result}")
    if (result != null) {
        println("欢迎${result}")
    } else {
        println("你的权限不够")
    }

    // name.takeIf { true/false }
    // true: 直接返回name本身
    // false: 直接放回null

    // 真正的用途
    println(checkPermissionAction2("Root", "!@#$"))

    // 小结:一般大部分情况下,都是 takeIf + 空合并操作符 = 一起使用
}

// 前端
public fun checkPermissionAction(name: String, pwd: String) : String? {
    return name.takeIf { permissionSystem(name, pwd) }
}

// takeIf + 空合并操作符
public fun checkPermissionAction2(name: String, pwd: String) : String {
    return name.takeIf { permissionSystem(name, pwd) } ?: "你的权限不够"
}

// 权限系统
private fun permissionSystem(username: String, userpwd: String) : Boolean {
    return if (username == "Root" && userpwd == "!@#$") true  else false
}

45、Kotlin的takeUnless内置函数

takeIf 和 takeUnless 功能是相反的

name.takeIf { true/false }  true:返回name本身,false返回null

 name.takeUnless { true/false }  false:返回name本身,true返回null

class Manager {

    private var infoValue: String? = null

    fun getInfoValue() /* : String? */ = infoValue

    fun setInfoValue(infoValue: String) {
        this.infoValue = infoValue
    }
}

fun main() {
    val manager = Manager()

    /*
    "Derry".takeIf { *//*it == "Merry"*//* }
    "Derry".takeUnless { *//*it == "Merry"*//* }
    */

    // manager.setInfoValue("AAA")

    // 小结:takeUnless+it.isNullOrBlank() 一起使用,可以验证字符串有没有初始化等功能
    val r  = manager.getInfoValue().takeUnless { it.isNullOrBlank() } ?: "未经过任何初始化值"
    println(r)
}

46、Kotlin的List创建与元素获取学习

  • 普通取值方式:    索引
  •  防止奔溃取值方式: getOrElse getOrNull
fun main() {
    val list = listOf("Merry", "Zhangsan", "Lisi", "Wangwu")

    // 普通取值方式:    索引  内部是运算符重载 [] == get
    println(list[0])
    println(list[1])
    println(list[2])
    println(list[3])
    // println(list[4]) // 奔溃  java.lang.ArrayIndexOutOfBoundsException: 4

    println()

    // 我们写KT代码,一定不会再出现,空指针异常,下标越界异常
    // 防止奔溃取值方式: getOrElse getOrNull
    println(list.getOrElse(3) {"越界"})
    println(list.getOrElse(4) {"你越界了"})
    println(list.getOrElse(4402) {"你越界了啊"})

    println()

    println(list.getOrNull(1))
    println(list.getOrNull(4))
    println(list.getOrNull(111))
    // getOrNull + 空合并操作符
    println(list.getOrNull(222) ?: "你越界了哦哦")

    // 小结:开发过程中,尽量使用 getOrElse 或 getOrNull,才能体现KT的亮点
}

 47、Kotlin的可变List集合学习

 可变的集合
 不可变集合 to 可变集合  toMutableList()

 可变集合 to 不可变集合  toList()

fun main() {
    // 可变的集合
    val list = mutableListOf("Merry", "Zhangsna", "Wangwu")
    // 可变的集合,可以完成可变的操作
    list.add("赵六")
    list.remove("Wangwu")
    println(list)

    // 不可变集合 to 可变集合
    val list2 = listOf(123, 456, 789)
    // 不可以的集合,无法完成可变的操作
    // list2.add
    // list2.remove

    val list3 : MutableList<Int> = list2.toMutableList()
    // 可变的集合,可以完成可变的操作
    list3.add(111)
    list3.remove(123)
    println(list3)

    // 可变集合 to 不可变集合
    val list4: MutableList<Char> = mutableListOf('A', 'B', 'C')
    // 可变的集合,可以完成可变的操作
    list4.add('Z')
    list4.remove('A')
    println(list4)

    val list5: List<Char> = list4.toList()
    // 不可以的集合,无法完成可变的操作
    /*list5.add
    list5.remove*/
}

48、Kotlin的mutator函数学习

  • mutator += -= 操作
  • removeIf
fun main() {
    // 1.mutator += -= 操作
    val list : MutableList<String> = mutableListOf("Merry", "MerryAll", "MerryStr", "Zhangsan")
    list += "李四" // mutator的特性 +=  -+ 其实背后就是 运算符重载而已
    list += "王五"
    list -= "Merry"
    println(list)

    // 2.removeIf
    // list.removeIf { true } // 如果是true 自动变量整个可变集合,进行一个元素一个元素的删除
    list.removeIf { it.contains("Merr") } // 过滤所有的元素,只要是有 Merr 的元素,就是true 删除
    println(list)
}

 49、Kotlin的List集合遍历学习

fun main() {
    val list = listOf(1, 2, 3, 4, 5, 6, 7)

    println(list) // 输出list详情而已,这个不是遍历集合

    // 第一种 遍历方式:
    for (i in list) {
        print("元素:$i  ")
    }

    println()

    // 第二种 遍历方式:
    list.forEach {
        // it == 每一个元素
        print("元素:$it  ")
    }

    println()

    // 第三种 遍历方式:
    list.forEachIndexed { index, item ->
        print("下标:$index, 元素:$item    ")
    }
}

50、Kotlin的解构语法过滤元素学习

  • 集合配合解构语法
  • 反编译看Java给三个变量赋值的代码
  • 解构屏蔽接收值
fun main() {
    val list: List<String> = listOf("李元霸", "李小龙", "李连杰")

    val(value1, value2, value3) = list
    // value1 = ""  val只读的
    println("value1:$value1, value2:$value2, value3:$value3")

    var(v1, v2, v3) = list
    // v1 = "OK"
    println("v1:$v1, v2:$v2, v3:$v3")

    // 用_内部可以不接收赋值,可以节约一点性能
    val(_ , n2, n3) = list
    // println(_) _不是变量名,是用来过滤解构赋值的,不接收赋值给我
    println("n2:$n2, n3:$n3")
}

 51、Kotlin的Set创建与元素获取

  • set 定义 不允许重复
  • 普通方式elementAt 会越界奔溃
  • elementAtOrElse elementAtOrNull
fun main() {
    val set: Set<String> = setOf("lisi", "wangwu", "zhaoliu", "zhaoliu") // set集合不会出现重复元素的
    println(set)
    // set[0] 没有这样 [] 的功能 去Set集合元素
    println(set.elementAt(0)) // [0]
    println(set.elementAt(1))
    println(set.elementAt(2))
    // println(set.elementAt(3)) // [3] 奔溃 会越界
    // println(set.elementAt(4)) // [4] 奔溃 会越界

    println()

    // 使用 list 或 set 集合,尽量使用  此方式,防止越界奔溃异常
    println(set.elementAtOrElse(0) {"越界了"})
    println(set.elementAtOrElse(100) {"越界了了"})

    println(set.elementAtOrNull(0))
    println(set.elementAtOrNull(111))
    // OrNull + 空合并操作符  一起使用
    println(set.elementAtOrNull(88) ?: "你越界啦啊")
}

52、Kotlin的可变Set集合

fun main() {
   val set : MutableSet<String> = mutableSetOf("A", "B")
    set += "C"
    set += "D"
    set -= "D"
    set.add("E")
    set.remove("E")
    println(set)
}

53、Kotlin的集合转换与快捷函数学习

  • 定义可变list集合
  • List 转 Set 去重
  • List 转 Set 转 List 也能去重
  • 快捷函数去重 distinct
fun main() {
   val list : MutableList<String> = mutableListOf("A", "A", "A", "B", "C") // list 可以重复元素
    println(list)

    // List 转 Set 去重
    val set /*: Set<String>*/ = list.toSet()
    println(set)

    // List 转 Set 转 List 也能去重
    val list2 /*: List<String>*/ = list.toSet().toList()
    println(list2)

    // 快捷函数去重 distinct
    println(list.distinct()) // 内部做了:先转变成 可变的Set结合  在转换成 List集合
    println(list.toMutableSet().toList()) // 和上面代码等价
}

 54、Kotlin中的数组类型

 Kotlin语言中的各种数组类型,虽然是引用类型,背后可以编译成Java基本数据类型
    IntArray        intArrayOf
    DoubleArray     doubleArrayOf
    LongArray       longArrayOf
    ShortArray      shortArrayOf
    ByteArray       byteArrayOf
    FloatArray      floatArrayOf
    BooleanArray    booleanArrayOf
    Array<对象类型>           arrayOf         对象数组

// 1.intArrayOf 常规操作的越界奔溃
// 2.elementAtOrElse elementAtOrNull
// 3.List集合转 数组
// 4.arrayOf Array<File>
fun main() {
    // 1.intArrayOf 常规操作的越界奔溃
    val intArray /*: IntArray*/ = intArrayOf(1, 2, 3, 4, 5)
    println(intArray[0])
    println(intArray[1])
    println(intArray[2])
    println(intArray[3])
    println(intArray[4])
    // println(intArray[5]) // 奔溃:会越界异常

    println()

    // 2.elementAtOrElse elementAtOrNull
    println(intArray.elementAtOrElse(0) { -1 })
    println(intArray.elementAtOrElse(100) { -1 })

    println(intArray.elementAtOrNull(0))
    println(intArray.elementAtOrNull(200))

    // OrNull + 空合并操作符 一起来用
    println(intArray.elementAtOrNull(666) ?: "你越界啦啊啊啊")

    println()

    // 3.List集合转 数组
    val charArray /*: CharArray*/ = listOf('A', 'B', 'C').toCharArray()
    println(charArray)

    // 4.arrayOf Array<File>
    val objArray /*: Array<File>*/ = arrayOf(File("AAA"), File("BBB"), File("CCC"))
}

55、Kotlin的Map的创建

fun main() {
    val mMap1 : Map<String, Double> = mapOf<String, Double>("A" to(534.4), "B" to 454.5)
    val mMap2 = mapOf(Pair("A", 545.4), Pair("B", 664.4))
    // 上面两种方式是等价的哦
}

56、Kotlin的读取Map的值

  • 方式一 [] 找不到会返回null
  •  方式二 getOrDefault
  •  方式三 getOrElse
  • 方式四 getValue()与Java一样 会奔溃
fun main() {
    val mMap /*: Map<String, Int>*/ = mapOf("A" to 123,"B" to 654)

    // 方式一 [] 找不到会返回null
    println(mMap["A"]) // 背后对[] 运算符重载了
    println(mMap["B"])
    println(mMap.get("A")) // get 与 [] 完完全全等价的
    println(mMap["XXX"]) // map通过key找 如果找不到返回null,不会奔溃

    println()

    // 方式二 getOrDefault
    println(mMap.getOrDefault("A", -1))
    println(mMap.getOrDefault("C", -1))

    // 方式三 getOrElse
    println(mMap.getOrElse("A") {-1})
    println(mMap.getOrElse("C") {-1})

    println()

    // 方式四 getValue 与Java一样 会奔溃  尽量不要使用此方式
    println(mMap.getValue("A"))
    println(mMap.getValue("XXX"))

    // map获取内容,尽量使用 方式二 方式三
}

 57、Kotlin的遍历Map

fun main() {
    val map /*: Map<String, Int>*/ = mapOf(Pair("A", 123), Pair("B", 456), "C" to 789)

    // 第一种方式:
    map.forEach {
        // it 内容 每一个元素 (K 和 V)  每一个元素 (K 和 V)  每一个元素 (K 和 V)
        // it 类型  Map.Entry<String, Int>
        println("K:${it.key} V:${it.value}")
    }

    println()

    // 第二种方式:
    map.forEach { key: String, value: Int ->
        // 把默认的it给覆盖了
        println("key:$key, value:$value")
    }

    println()

    // 第三种方式:
    map.forEach { (k /*: String*/, v /*: Int*/) ->
        println("key:$k, value:$v")
    }

    println()

    // 第四种方式:
    for (item /*: Map.Entry<String, Int>*/ in map) {
        // item 内容 每一个元素 (K 和 V)  每一个元素 (K 和 V)  每一个元素 (K 和 V)
        println("key:${item.key} value:${item.value}")
    }

}

58、Kotlin的可变Map集合

  • 可变集合的操作 += [] put
  • getOrPut 没有的情况
  • getOrPut 有的情况
fun main() {
    // 1.可变集合的操作 += [] put
    val map : MutableMap<String, Int> = mutableMapOf(Pair("A", 123), "B" to 456, Pair("Dee", 789))
    // 下面是可变操作
    map += "AAA" to(111)
    map += "BBB" to 1234
    map -= "A"
    map["CCC"] = 888
    map.put("DDD", 999) // put 和 [] 等价的

    // 2.getOrPut 没有有的情况
    // 如果整个map集合里面没有 FFF的key 元素,我就帮你先添加到map集合中去,然后再从map集合中获取
    val r: Int = map.getOrPut("FFF") { 555 }
    println(r)
    println(map["FFF"]) // 他已经帮你加入进去了,所以你可以获取

    // 3.getOrPut 有的情况
    val r2 = map.getOrPut("B") {666} // 发现Derry的key是有的,那么就直接获取出来, 相当于666备用值就失效了
    println(r2)
}

 59、Kotlin的定义类与field关键字

class KtBase {
    var name = "A"
        get() = field
        set(value) {
            field = value
        }
    /* 背后做的事情:

       @NotNull
       private String name = "A";

       public void setName( @NotNull String name) {
            this.name = name;
       }

       @NotNull
       public String getName() {
            return this.name;
       }

     */

    var value = "ABCDEFG"
        // 下面的隐式代码,不写也有,就是下面这个样子
        get() = field
        set(value) {
            field = value
        }

    var info = "abcdefg ok is success"
        get() = field.capitalize() // 把首字母修改成大写
        set(value) {
            field = "**【$value】**"
        }
    /* 背后做的事情:

        @NotNull
        private String info = "abcdefg ok is success";

        public void setInfo( @NotNull String info) {
            this.info = "**【" + info + "】**";
        }

        @NotNull
        public String getInfo() {
            return StringKt.capitalize(this.info)
        }

     */
}

// public final class KtBaseKt { 下面的main函数 }


fun main() {
    // 背后隐式代码:new KtBase().setName("C");
    KtBase().name = "C"
    // 背后隐式代码:System.out.println(new KtBase().getName());
    println(KtBase().name)


    println(">>>>>>>>>>>>>>>>>>")


    // 背后隐式代码:System.out.println(new KtBase().getInfo());
    println(KtBase().info)

    // 背后隐式代码:new KtBase().setInfo("学习KT");
    KtBase().info = "学习KT"
}

第二部分: 

kotlin基础2

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值