1.数组
数组在 Kotlin 中使用 Array 类来表示,它定义了 get 与 set 函数(按照运算符重载约定这会转变为 [])以及 size 属性,以及一些其他有用的成员函数:
class Array<T> private constructor() {
val size: Int
operator fun get(index: Int): T
operator fun set(index: Int, value: T): Unit
operator fun iterator(): Iterator<T>
// ……
}
我们可以使用库函数 arrayOf() 来创建一个数组并传递元素值给它,这样 arrayOf(1, 2, 3) 创建了 array [1, 2, 3]。 或者,库函数 arrayOfNulls() 可以用于创建一个指定大小的、所有元素都为空的数组。
另一个选项是用接受数组大小以及一个函数参数的 Array 构造函数,用作参数的函数能够返回给定索引的每个元素初始值:
// 创建一个 Array<String> 初始化为 ["0", "1", "4", "9", "16"]
val asc = Array(5, { i -> (i * i).toString() })
asc.forEach { println(it) }
如上所述,[] 运算符代表调用成员函数 get() 与 set()。
Kotlin 也有无装箱开销的专门的类来表示原生类型数组: ByteArray、 ShortArray、IntArray 等等。这些类与 Array 并没有继承关系,但是它们有同样的方法属性集。它们也都有相应的工厂方法:
val x: IntArray = intArrayOf(1, 2, 3)
x[0] = x[1] + x[2]
2.字符串
字符串用 String 类型表示。字符串是不可变的。 字符串的元素——字符可以使用索引运算符访问: s[i]。 可以用 for 循环迭代字符串:
val str = "abcd"
for (c in str) {
println(c)
}
可以用 + 操作符连接字符串。这也适用于连接字符串与其他类型的值, 只要表达式中的第一个元素是字符串:
val s = "abc" + 1
println(s + "def")
字符串字面值:
Kotlin 有两种类型的字符串字面值: 转义字符串可以有转义字符,以及原始字符串可以包含换行以及任意文本。转义字符串很像 Java 字符串:
val s = "Hello, world!\n"
转义采用传统的反斜杠方式。
原始字符串 使用三个引号(""")分界符括起来,内部没有转义并且可以包含换行以及任何其他字符:
val text = """
for (c in "foo")
print(c)
"""
你可以通过 trimMargin()
函数去除前导空格:
val text = """
|Tell me and I forget.
|Teach me and I remember.
|Involve me and I learn.
|(Benjamin Franklin)
""".trimMargin()
默认 | 用作边界前缀,但你可以选择其他字符并作为参数传入,比如 trimMargin(">")。
字符串模板
字符串可以包含模板表达式 ,即一些小段代码,会求值并把结果合并到字符串中。 模板表达式以美元符($)开头,由一个简单的名字构成:
val i = 10
println("i = $i") // 输出“i = 10”
或者用花括号括起来的任意表达式:
val s = "abc"
println("$s.length is ${s.length}") // 输出“abc.length is 3”
原始字符串与转义字符串内部都支持模板。 如果你需要在原始字符串中表示字面值 $ 字符(它不支持反斜杠转义),你可以用下列语法:
val price = """
${'$'}9.99
"""
3.集合:List、Set、Map
Kotlin 区分可变集合与不可变集合(lists、sets、maps 等)。精确控制什么时候集合可编辑有助于消除 bug 以及设计良好的 API
Kotlin 的 List<out T> 类型是一个提供只读操作如 size、get等的接口。与 Java 类似,它继承自 Collection<T> 进而继承自 Iterable<T>。改变 list 的方法是由 MutableList<T> 加入的。这一模式同样适用于 Set<out T>/MutableSet<T> 及 Map<K, out V>/MutableMap<K, V>。
我们可以看下 list 及 set 类型的基本用法:
val numbers: MutableList<Int> = mutableListOf(1, 2, 3)
val readOnlyView: List<Int> = numbers
println(numbers) // 输出 "[1, 2, 3]"
numbers.add(4)
println(readOnlyView) // 输出 "[1, 2, 3, 4]"
readOnlyView.clear() // -> 不能编译
val strings = hashSetOf("a", "b", "c", "c")
assert(strings.size == 3)
Kotlin 没有专门的语法结构创建 list 或 set。 要用标准库的方法,如 listOf()
、 mutableListOf()
、 setOf()
、 mutableSetOf()
。 在非性能关键代码中创建 map 可以用一个简单的惯用法来完成:mapOf(a to b, c to d)
。
注意上面的 readOnlyView 变量(译者注:与对应可变集合变量 numbers)指向相同的底层 list 并会随之改变。 如果一个 list 只存在只读引用,我们可以考虑该集合完全不可变。创建一个这样的集合的一个简单方式如下:
val items = listOf(1, 2, 3)
目前 listOf 方法是使用 array list 实现的,但是未来可以利用它们知道自己不能变的事实,返回更节约内存的完全不可变的集合类型。
List 与 set 有很多有用的扩展方法值得熟悉:
val items = listOf(1, 2, 3, 4)
items.first() == 1
items.last() == 4
items.filter { it % 2 == 0 } // 返回 [2, 4]
val rwList = mutableListOf(1, 2, 3)
rwList.requireNoNulls() // 返回 [1, 2, 3]
if (rwList.none { it > 6 }) println("No items above 6") // 输出“No items above 6”
val item = rwList.firstOrNull()