Kotlin编程实战:创建优雅、富于表现力和高性能的JVM与Android应用程序
上QQ阅读APP看书,第一时间看更新

5.4 使用列表

作为创建列表的第一步,Kotlin希望你声明意图——不可变的或可变的。要创建一个不可变列表,需要使用listOf(),不可变是隐含的,当有选择的时候,这也是我们的首选。但是如果你真的需要创建一个可变列表,那么使用mutableListOf()。

函数listOf()返回对接口kotlin.collections.List<T>的引用。在下面的代码中,引用fruits就是这种接口类型,专用于参数类型的字符串:

要访问列表中的元素,可以使用传统的get()方法,但是索引运算符[]也可以使用同样的方法。

索引运算符[]引起的混乱要比get()小,而且更方便——可以随意地使用。可以使用contains()方法或使用in运算符来检查集合中是否存在某个值——我们将在12.1节中深入探讨运算符重载。

在前面的代码中,我们询问列表是否包含某个值以及该值是否在列表中——后者更流畅,在Kotlin中更受青睐。

使用listOf()返回的引用,我们不能修改列表。如果你是不接受“否定”回答那种类型的人,请使用以下代码验证一下:

接口kotlin.collections.List<T>充当JDK中广泛使用的对象的编译时视图,你将在Java中使用Arrays.asList()来创建该对象,但是该接口没有允许对列表进行转变或修改的方法。这就是在编译时对add()方法的调用失败的原因。通过提供这样的视图,Kotlin能够从不变性的角度使代码更安全,而不引入任何运行时开销或转换。

这种保护很好,但这不应该阻止我们还有另外一种水果。+运算符可以派上用场了。

该操作没有改变列表fruits,相反,它创建了一个新的列表,其中包含了从原始列表复制的所有值以及新元素。

如果有一个正号,那么期望有一个减号是合乎逻辑的。-运算符在创建一个没有指定元素的新的列表时很有用,如下所示:

如果指定的元素没有出现在列表中,那么结果是一个包含原始元素的列表,没有删除任何内容。

List<T>[1]接口在前面的示例中非常出色,Kotlin提供了一个很长的方法列表。fruits接口的类型是List<T>,但真正的类是什么呢?你可能想知道。让我们用下面的一段代码来回答这个问题:

输出显示实例是JDK中提供的类型,尽管我们使用Kotlin中的视图接口来访问它。

listOf()方法返回一个只读引用,但是如果你想创建一个可变列表,请拨打热线,这样他们会说服你不要这样做。但是,经过充分的思考和讨论,如果你认为这是正确的选择,那么可以使用mutableListOf()函数创建一个。你可以对List<T>执行的所有操作也可以在MutableList<T>的实例上使用。但是,使用此方法创建的实例是java.util.ArrayList的实例,而不是java.util.Arrays$ArrayList的。

在下一段代码中,我们将访问读写接口,而不是只读接口:

使用这个接口,我们可以改变列表。例如,我们可以向其添加一个元素:

不用通过mutableListOf()函数获得的MutableList<T>接口与ArrayList<T>进行交互,你可以使用arrayListOf()函数直接获得类型ArrayList<T>的引用。

在可能的情况下,使用listOf()而不是mutableListOf()和arrayListOf()——只是不情愿地引入了可变性。

一旦创建了一个列表,你就可以使用命令式风格对其进行遍历,就像我们在4.2节中所看到的那样,或者使用函数式风格,就像第11章中所看到的那样。

如果你不关心元素的顺序,那么你可能希望使用集合而不是列表,Kotlin为此提供了顶级函数。

[1] https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-list/index.html