【问题标题】:Difference between List and Array types in KotlinKotlin 中列表和数组类型的区别
【发布时间】:2016-07-15 17:02:43
【问题描述】:

ListArray 类型有什么区别?
似乎可以对它们进行相同的操作(循环、过滤表达式等),在行为或用法上有什么不同吗?

val names1 = listOf("Joe","Ben","Thomas")
val names2 = arrayOf("Joe","Ben","Thomas")

for (name in names1)
    println(name)
for (name in names2)
    println(name)

【问题讨论】:

    标签: arrays list kotlin


    【解决方案1】:

    Arrays 和列表(由List<T> 及其子类型MutableList<T> 表示)有很多不同之处,这里是最重要的:

    • Array<T> 是一个具有已知实现的类:它是一个顺序固定大小的内存区域,用于存储项目(在 JVM 上它由 Java array 表示)。

      List<T>MutableList<T>是接口,有不同的实现:ArrayList<T>LinkedList<T>等。列表的内存表示和操作逻辑在具体实现中定义,例如LinkedList<T> 中的索引会通过链接并花费 O(n) 时间,而 ArrayList<T> 将其项目存储在动态分配的数组中。

      val list1: List<Int> = LinkedList<Int>()
      val list2: List<Int> = ArrayList<Int>()
      
    • Array&lt;T&gt; 是可变的(可以通过对它的任何引用来更改),但List&lt;T&gt; 没有修改方法(它是read-only view of MutableList&lt;T&gt;immutable list implementation)。

      val a = arrayOf(1, 2, 3)
      a[0] = a[1] // OK
      
      val l = listOf(1, 2, 3)
      l[0] = l[1] // doesn't compile
      
      val m = mutableListOf(1, 2, 3)
      m[0] = m[1] // OK
      
    • 数组具有固定大小,不能扩展或缩小保留标识(您需要复制一个数组来调整它的大小)。对于列表,MutableList&lt;T&gt;addremove 函数,可以增加和减少它的大小。

      val a = arrayOf(1, 2, 3)
      println(a.size) // will always be 3 for this array
      
      val l = mutableListOf(1, 2, 3)
      l.add(4)
      println(l.size) // 4
      
    • Array&lt;T&gt;invariant on TArray&lt;Int&gt; 不是 Array&lt;Number&gt;),MutableList&lt;T&gt; 相同,但 List&lt;T&gt; 是协变的(List&lt;Int&gt;List&lt;Number&gt;)。

      val a: Array<Number> = Array<Int>(0) { 0 } // won't compile
      val l: List<Number> = listOf(1, 2, 3) // OK
      
    • 数组针对原语进行了优化:有单独的IntArrayDoubleArrayCharArray 等映射到 Java 原语数组(int[]double[]char[]),而不是boxed 个(Array&lt;Int&gt; 映射到 Java 的 Integer[])。列表通常没有针对原语优化的实现,尽管一些库(JDK 之外)提供了原语优化列表。

    • List&lt;T&gt;MutableList&lt;T&gt;mapped types 并且在 Java 互操作性中具有特殊行为(Java 的 List&lt;T&gt; 在 Kotlin 中被视为 List&lt;T&gt;MutableList&lt;T&gt;)。数组也被映射,但它们具有other rules 的 Java 互操作性。

    • annotations 中使用了某些数组类型(原始数组、Array&lt;String&gt; 和带有enum class 条目的数组),还有一个特殊的array literal syntax for annotations。列表和其他集合不能用于注释。

    • 关于用法,除了代码的性能关键部分外,好的做法是在任何地方都优先使用列表而不是数组,原因与that for Java 相同。

    【讨论】:

      【解决方案2】:

      与使用方面的主要区别在于Arrays 具有固定大小,而(Mutable)List 可以动态调整其大小。此外,Array 是可变的,而 List 不是。

      此外,kotlin.collections.List 是由java.util.ArrayList 实现的接口。它还由kotlin.collections.MutableList 扩展,以便在需要允许修改项目的集合时使用。

      在 jvm 级别,Arrayarrays 表示。另一方面,Listjava.util.List 表示,因为 Java 中没有等效的不可变集合。

      【讨论】:

      • 我在这里并不完全相信。 Array 中有什么是可变的?只有它的元素 - 在List 中相同。 List 的大小也是固定的。
      • @AndroidEx 下面将编译val intArray = arrayOf(1,2,3); intArray[0] = 2,而这不会编译val intList = listOf(1,2,3); intList[0] = 2List 确实有一个固定的大小,但 MutableList 扩展它没有,因此 val a:List&lt;Int&gt; 可能会在后续调用中报告不同的 size
      • 推荐使用List还是ArrayList
      • @IgorGanapolsky 如果您不关心具体的实现,请使用List(可能是 99% 的情况?)。如果您确实关心实现,请使用 ArrayListLinkedList 或任何其他具体实现。
      【解决方案3】:

      除此之外,身份比较也不同:

      val l1 = listOf("a")
      val l2 = listOf("a")
      var x = (l1 == l2) // => true
      
      val a1 = arrayOf("a")
      val a2 = arrayOf("a")
      var y = (a1 == a2) // => false
      

      【讨论】:

        猜你喜欢
        • 2020-11-19
        • 1970-01-01
        • 2015-04-26
        • 2011-03-30
        • 1970-01-01
        • 2011-02-12
        • 2017-10-30
        相关资源
        最近更新 更多