Kotlin基础知识(十二)——基本数据类型和其他数据类型

524 阅读4分钟

一、可空性和集合

  • 创建一个包含可空值的集合
fun readNumbers(reader: BufferedReader): List<Int?> {
    // 创建包含可空Int值的列表
    val result = ArrayList<Int?>()
    for (line in reader.linesSequence()) {
        try {
            // 向列表添加整数(非空值)
            val number = line.toInt()
            result.add(number)
        }
        catch(e: NumberFormatException) {
            // 向列表添加null,因为当前行不能被解析为整数
            result.add(null)
        }
    }
    return result
}

List<Int?>是能持有Int?类型值的列表:换句话说,可以持有Int或者null

注意:变量自己类型的可空性和用作类型参数的类型的可空性是有区别的。包括可空Int的列表和包含Int的可空列表之间的区别如图1:

图1 集合的元素和集合本身可空性

在第一种情况下,列表本身始终不为null,但列表中的每个值都可以为null。第二种类型的变量可能包含空引用而不是列表实例,但列表中的元素保证是非空的

Kotlin提供了一个标准库函数***filterNotNull***:遍历一个包含可空值的集合并过滤掉null。

二、只读集合与可变集合

Kotlin的集合设计和Java不同的另一项重要特质是,它把访问集合数据的接口和修改集合数据的接口分开了。这种区别存在于最基础的使用集合的接口之中:kotlin.collections.Collection。使用这个接口,可以遍历集合中的元素、获取集合大小、判断集合中包含某个元素,以及执行其他从该集合中读取数据的操作。但这个接口没有任何添加或移除元素的方法。

使用***kotlin.collections.MutableCollection接口可以修改集合中的数据。它继承了普通的kotlin.collections.Collection*接口,还提供了方法来添加和移除元素、清空元素**等。

  • 只读集合:函数接受***Collection而不是MutableCollection作为形参,只能读取数据*。
  • 可变集合:函数要求接受***MutableCollection形参,则是可以修改数据*。
// 定义
fun <T> copyElements(source: Collection<T>, target: MutableCollection<T>) {
    // 在source集合中的所有元素中循环
    for(item in source) {
        target.add(item)
    }
}

// 测试
>>> val source: Collection<Int> = arrayListOf(3, 5, 7)
>>> val target: MutableCollection<Int> = arrayListOf(1)
>>> copyElements(source, target)
>>> println(target)
[1, 3, 5, 7]

注意:只读集合不一定是不可变的。因为它可能只是同一个集合的众多引用中的一个。任何其他的引用都可能拥有一个可变接口类型。

只读集合总是线程安全的。如果你在多线程环境下处理数据,需要保证代码正确地同步了对数据的访问。


集合创建函数

集合类型只读可变
ListlistOfmutableListOf、arrayListOf
SetSetOfmutableSetOf、hashSetOf、LinkedSetOf、sortedSetOf
MapmapOfmutableMapOf、hashMapOf、LinkedMapOf、sortedMapOf

四、对象和基本数据类型的数组

要在Kotlin中创建数组,有下面这些方法供你选择:

  • **arrayOf函数创建一个数组,它包含的元素是指定为该函数的实参
  • arrayOfNulls创建一个给定大小的数组,包含的是null元素。当然,它只能用来创建包含元素类型可空的数组**。
  • *Array*构造方法接受数组的大小和一个lambda表达式,调用lambda表达式来创建每一个数组元素。这就是使用非空元素类型初始化数组,但不能显示地传递每个元素的方式。

为了表示基本数据类型的数组,Kotlin提供了若干独立的类,每一种基本数据类型都对应一个。如,Int类型值的数组叫做IntArray。Kotlin还提供了***ByteArray、CharArray、BooleanArray等给其他类型。所有这些类型都被编译成普通的Java基本数据类型数组,比如int[]、byte[]、char[]***等


要创建一个基本数据类型的数组,你有如下选择

  • 该类型的构造方法接受***size参数并返回一个使用对应基本数据类型默认值*(通常是0)初始化号的数组
  • 厂函数(IntArray的intArrayOf,以及其他数据类型的函数)接受变长参数的值并创建存储这些值的数组
  • 另一种构造方法,接受一个大小和一个用于初始化每个元素的lambda
val fiveZeros = IntArray(5)
val fiveZwrosToo = intArrayOf(0, 0, 0, 0, 0)

>>> val squares = IntArray(5) { i -> (i + 1) * (i + 1) }
>>> println(squares.joinToString())
1, 4, 9, 16, 25