Kotlin学习笔记 第四章 解构声明 集合集合的扩展方法 Range 异常 Throw关键字

这篇博客详细介绍了Kotlin中的解构声明,包括在数据类、函数返回多个结果、集合中的应用,以及解构声明的类型。同时,讲解了集合的只读视图、Set的创建与遍历、List的便利方法、Map操作和范围操作。此外,还涵盖了异常处理和throw表达式的使用。通过实例展示了如何在Kotlin中高效地处理数据和控制流程。
摘要由CSDN通过智能技术生成

参考链接

Kotlin官方文档

https://kotlinlang.org/docs/home.html

中文网站

https://www.kotlincn.net/docs/reference/properties.html

本系列为参考Kotlin中文文档

https://download.csdn.net/download/u011109881/21418027

整理的笔记 

pdf也可以在这里下载

https://www.kotlincn.net/docs/kotlin-docs.pdf

大部分示例来自bilibili Kotlin语言深入解析 张龙老师的视频

1 解构声明

知识点

1 解构声明在数据类中的应用

2 一个函数返回多个结果

3 解构声明在集合中的应用

4 解构声明的类型

笔记

/**
 * 解构声明
 * 可以理解为批量赋值 常用于数据类和Map等拥有多个属性的类型
 * 目的是方便我们声明和获取其中的属性
 */

fun main() {
    // 1 解构声明在数据类中的应用
    // 普通Java类的获取方式
    val myPerson = generatePerson()
    println(myPerson.name)
    println(myPerson.age)
    println(myPerson.address)
    // 使用解构声明
    // 批量声明与赋值
    val (myName, myAge, myAddress) = generatePerson()
    println(myName)
    println(myAge)
    println(myAddress)
    println("======= 1 end ========")

    // 2 一个函数返回多个结果
    // --使用Pair或Triple
    val triple = generatePerson2()
    println(triple.first)
    println(triple.second)
    println(triple.third)
    // 想要一个return里面返回多个数据 一个是利用解构声明 一个是利用Pair或Triple
    // 但是两者区别还是挺大的 Pair或Triple只是存储了多个结果 但是并没有解构声明容易理解 因为Pair或Triple并没有固定的数据类型
    // 而结构声明返回的数据类型 是我们创建map或者数据类时就制定好了类型的
    // 所以更推荐解构声明
    println("======= 2 end ========")

    // 3 解构声明在集合中的应用
    // map 初始化   to关键字本身是一个中缀表达式 返回一个pair
    // 3.1 利用解构声明遍历map
    val map = mapOf("a" to "aa", "b" to "bb", "c" to "cc") // 类型可以推断出来 所以可以省略
    val map2 = mapOf<String, String>("a" to "aa", "b" to "bb", "c" to "cc")

    for ((myKey, myValue) in map) {
        println("key:$myKey value:$myValue")
    }
    println("----------------------")
    // 3.2 利用mapValues方法修改map的value
    // mapValues:map以<K,V>的类型输入 以<K,R>的形式输出
    // mapValues接受一个函数作为参数 该函数参数为Map.Entry<K,V> 返回R类型的数据
    // mapKeys和mapValues方法差不过 差异在于mapKeys修改的是key而不是value
    map.mapValues { entry ->
        "...value changed to:${entry.key} ${entry.value}"
    }.forEach { println(it) }
    println("----------------------")
    // 3.3 mapValues+结构声明 修改value同时遍历map
    map.mapValues { (_, value) ->
        "$value haha"// 给value加上haha
    }.forEach { println(it) }

    println("======= 3 end ========")

    // 4 解构声明的类型
    // kotlin 允许我们我们为解构声明的整体指定类型 也允许我们给每个元素指定类型
    // 给每个元素指定类型
    map.mapValues { (key: String, value: String) -> "$value haha" }.forEach { println(it) }
    // 给整体指定类型
    map.mapValues { (key, value): Map.Entry<String, String> -> "$value hihi" }.forEach { println(it) }
    // 也可以省略
    map.mapValues { (key, value) -> "$value enen" }.forEach { println(it) }

}

// 2 一个函数返回多个结果
fun generatePerson2(): Triple<String, Int, String> {
    return Triple("zhangsan", 25, "shanghai")
}


// 1 解构声明在数据类中的应用
data class Person(val name: String, val age: Int, val address: String)

fun generatePerson(): Person {
    return Person("zhangsan", 25, "shanghai")
}

class D0501DestructuringDeclaration {
}

2 集合

知识点

1 只读视图demo

2 set的创建与遍历

3 只读列表是协变的(out)

4 快照 snapshot

笔记

/**
 * 可变集合与不可变集合
 *
 * kotlin 严格区分可变集合和不可变集合
 * 重点是区分真正的不可变集合与可变集合的只读视图
 * 在kotlin中 mutable修饰的集合是可变的 没有mutable修饰的则是不可变的
 * 例如 MutableList创建的是可变集合 List创建的是不可变集合
 *
 * List继承自Collection Collection又继承自Iterable 因此它只有访问的方法
 * MutableList除了继承自 List 还继承自MutableCollection MutableCollection则提供了一系列add remove等修改list内容的方法
 * 只读视图虽然本身无法修改内容 但是如果它的原引用内容变化 视图里面的内容也发生变化
 */
fun main() {
    // 1 只读视图demo
    // 创建一个可变集合
    val stringList: MutableList<String> = mutableListOf("hello", "world", "hello world")
    // 创建一个可变集合的只读视图
    val readOnlyView: List<String> = stringList
    println(stringList)
    stringList.add("welcome")
    println(stringList)
    // 因为readOnlyView是stringList的只读视图 因此stringList发生了变化 readOnlyView内容自然变化
    // 但是readOnlyView自身无法调用修改内容的接口
    println(readOnlyView)
    // readOnlyView.clear//报错 无法调用修改的接口
    println("=========== 1 end ===============")

    // 2 set的创建与遍历
    val mySet: HashSet<String> = hashSetOf("a", "b", "c", "c")
    mySet.forEach { println(it) }
    println("=========== 2 end ===============")
    // 3 只读列表是协变的(out)
    // 原因是 它只用于从集合中取出数据 是生产者 而不会消费数据(更改内容)
    val myString: List<String> = listOf("a", "b")
    val s2: List<Any> = myString // List<String> 好像赋值给了 List<Any> 子类型赋值给父类型---协变
    println("=========== 3 end ===============")
    // 4 快照 snapshot
    val origin = mutableListOf("a", "b", "c")
    val snapshot = origin.toList()// toList 是一个Iterable的扩展方法 只是赋值集合中的元素 返回的是一个不可变的list
    origin.add("d")
    println(origin)
    println(snapshot)
    // snapshot.clear()// 报错
    println("=========== 4 end ===============")
}

class D0502Collection {
}

3 集合的便利方法

知识点

1 List的便利方法

2 map demo

笔记

// 集合的便利方法

fun main() {
    // 1 List的便利方法
    val item = listOf(1, 2, 3, 4)
    // 取出列表第一个元素
    println(item.first())
    // 取出列表最后一个元素
    println(item.last())
    // Returns the first element, or null if the list is empty.
    println(item.firstOrNull())
    println(item.lastOrNull())

    // 传入lambda表达式过滤列表
    item.filter { it % 2 == 0 }.forEach { println(it) }
    println("--------------")

    val myList = mutableListOf(1, 2, 3)
    // none方法传入一个lambda表达式 如果表达式成立 none返回true 否则返回false
    if (myList.none { it > 10 }) {
        println("没有大于十的元素")
    } else {
        println("存在>10的元素")
    }
    // requireNoNulls 如果myList中没有null 返回List 否则抛出IllegalArgumentException异常
    println(myList.requireNoNulls())
    println("======== 1 end ========")

    // 2 map demo
    val myMap = hashMapOf("hello" to 1, "word" to 2)
    // 通过下标访问Map
    println(myMap["hello"])

    val myMap2: Map<String, Int> = HashMap(myMap) // myMap2是myMap元素的拷贝 且无法修改
    println(myMap2)
    // 通过下标增加map的元素
    myMap["hi"] = 3
    println(myMap)
    println(myMap2)
    // myMap2["hi"] = 3 // myMap2是只读的
}

class D0503CollectionConvenientMethod {

}

4 range

笔记

// range

fun main() {
    // 1 输出4
    val i = 4
    if (i in 1..5) {
        println(i)
    }
    println("---------------")
    // 输出1-4
    for (a in 1..4) {
        println(a)
    }
    println("---------------")
    // 什么输出都没有
    for (a in 4..1) {
        println(a)
    }
    println("---------------")
    // 降序输出
    for (a in 4 downTo 1) {
        println(a)
    }
    println("---------------")

    for (a in 1..6 step 2) {
        println(a)
    }
    println("---------------")
    // 输出1-4 [1,4)
    for (a in 1 until 4) {
        println(a)
    }
    println("---------------")
}

class D0504Range {
}

5 异常

笔记

import java.lang.NumberFormatException
import javax.xml.bind.DatatypeConverter.parseInt

// 异常
// Kotlin 中的异常是一个表达式
// Kotlin 中所有的异常都是运行时异常 没有checked exception
fun main() {
    val s = "a"
    // 如下所示
    // res的值可能是try中的最后一句表达式的值 或者 catch中的最后一句表达式的值
    val res: Int? = try {
        parseInt(s)
    } catch (ex: NumberFormatException) {
        null
    } finally {
        println("finally invoked")
    }
    println(res)
}

class D0505Exception {
}

6 throw

知识点

1 Elvis 表达式

2 throw表达式

3 各种item赋值为null 类型推断

笔记

import java.lang.IllegalArgumentException

/**
 * throw
 * throw在Kotlin中是一个表达式
 * throw表达式的类型是一种特殊的类型:Nothing
 * 在自己的代码中 可以使用Nothing来代表永远不会返回的函数
 */

fun main() {
    // 1 Elvis 表达式
    // Elvis是 ?: 它的含义是 如果该表达式的前半部分不为空 则该表达式的值为前半部分 否则为后半部分
    val str: String? = "aa" // null
    val str2 = str ?: throw IllegalArgumentException("不能传入空")
    println(str2)
    println("=========1 end ==========")

    // 2 throw表达式 返回Nothing类型
    val str3: String? = "bb" // null
    val str4 = str3 ?: myMethod("")
    println(str4)

    // 3 各种item赋值为null 类型推断
    // 赋值为null
    // 类型推断为Nothing?
    val myNull = null
    println(myNull is Nothing?)
    // list元素赋值为null
    // list类型推断为List<Nothing?>
    val s2 = listOf(null)
    println(s2 is List<Nothing?>)

}

fun myMethod(message: String): Nothing {
    throw IllegalArgumentException(message)
}

class D0506Throw {

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值