Kotlin快速运用第三阶段(空安全、字符串、内置函数等)

Kotlin语言的可空性特点

fun main() {

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

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

    println(name)

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

Kotlin语言的安全调用操作符

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

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

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

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

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

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

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

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

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

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

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

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

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

在Kotlin空合并操作符

fun main() {
    var info: String? = "李小龙"
    // info = null

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


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

在这里插入图片描述

在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("你的代码太不严谨了")

在这里插入图片描述

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

在这里插入图片描述

Kotlin语言的substring

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

在这里插入图片描述

Kotlin语言的split操作

fun main() {
    val jsonText = "Derry,Leo,Lance,Alvin"
    // 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")
}

在这里插入图片描述

Kotlin语言的replace完成加密解码操作

// ABCDEFGHIJKLMNOPQRSTUVWXYZ
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")
}

在这里插入图片描述

Kotlin语言的== 与 ===比较操作

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

    val name1 : String = "Derry"
    val name2 : String = "Derry"
    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 = "derry".capitalize() // 修改成"Derry"
    println(name4 === name1)
}

在这里插入图片描述

Kotlin语言的字符串遍历操作

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

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 此函数
}

Kotlin语言中Double转Int与类型格式化

// 65.4645654 65.8343433
fun main() {
    println(65.4645654.toInt()) // 

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

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

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

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

}

Kotlin语言的apply内置函数

fun main() {
    val info = "Derry 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())
    }
}

在这里插入图片描述

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*/ "Derry"))

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

// 普通方式 对值判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,你在搞什么飞机"

Kotlin语言的run内置函数

// 1.run函数的特点 字符串延时
// 2.具名函数判断长度 isLong
// 3.具名函数监测合格 showText
// 4.具名函数增加一个括号 mapText
// 5.具名函数输出内容

fun main() {
    val str = "Derry 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】"

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)

Kotlin语言的also内置函数

// "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
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没有任何影响
}

Kotlin语言的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
}

Kotlin语言的takeUnless内置函数

// takeIf 和 takeUnless 功能是相反的
// name.takeIf { true/false } true:返回name本身,false返回null
// name.takeUnless { true/false } false:返回name本身,true返回null

// 为什么有 takeUnless 的出现,一个 takeIf 不就够了吗?

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 == "Derry"*//* }
    "Derry".takeUnless { *//*it == "Derry"*//* }
    */

    // manager.setInfoValue("AAA")

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

gujunhe

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值