Kotlin中ArrayList<String>()和mutableListOf<String>()之间的区别

166
private val repositories = mutableListOf<String>()

private val repositories = ArrayList<String>()

两者都是可变列表,那么使用mutableListOf或者ArrayList这两个关键字有何意义呢?

还是说它们之间存在重大区别?


15
mutableListOfArrayList在Kotlin中都不是关键字。 - Ilya
4个回答

215
两者唯一的区别就在于表达意图的方式不同。
当你写下val a = mutableListOf()时,你的意思是“我想要一个可变列表,但对具体实现并不特别关心”。而当你写下val a = ArrayList()时,你的意思是“我明确想要一个ArrayList”。
在Kotlin编译到JVM的当前实现中,调用mutableListOf会生成一个ArrayList,在行为上没有任何区别:一旦列表建立,所有的行为都是相同的。
现在,假设未来版本的Kotlin改变mutableListOf返回了一个不同类型的列表。
很有可能,只有在Kotlin团队确定新实现对大多数用例更有效时,他们才会进行这种更改。此时,mutableListOf将会透明地使用新的列表实现,并且你会免费获得更好的行为。如果这符合你的情况,请选择mutableListOf
另一方面,也许你花费了很多时间思考你的问题,并且认为ArrayList真的是最适合你的问题,你不想冒险被移到次优解。那么你可能想要直接使用ArrayList,或者使用arrayListOf工厂函数(与mutableListOf类似,但是用于ArrayList特定情况下)。

34

mutableListOf<T>() 是一个内联函数调用,返回一个MutableList<T>。截至今天,mutableListOf 确实会返回一个 ArrayList 的实例。

ArrayList<String>() 是一个构造函数调用,无法被内联。

换句话说,假设有:

 val a = mutableListOf<String>()
 val b = ArrayList<String>()
  • a 的类型为 MutableList<String>
  • b 的类型为 ArrayList<String>

在运行时,ab 都将保存一个 ArrayList 实例。

请注意,内联函数与类型擦除结合使用时尤为有用,这也解释了 listOfmutableListOf 等方法的存在。


2
所以没有任何区别。 - Sai
4
ab 声明的类型不同 - 因此在编译时存在差异。 - miensol
1
它可以作为 val b = arrayListOf<String>() 内联。 - Vlad

14
  • 在底层,mutableListOf()和arrayListOf()都会创建一个ArrayList实例。ArrayList是一个类,它恰好实现了MutableList接口。
  • 唯一的区别在于,arrayListOf()将ArrayList作为实际的ArrayList返回。mutableListOf()返回一个MutableList,因此实际的ArrayList被“伪装”成仅由MutableList接口所描述的部分。
  • 在实践中,区别在于ArrayList有一些不是MutableList接口的方法(trimToSize和ensureCapacity)。
  • 从哲学上讲,MutableList只关心返回的对象的行为。它只返回“表现得像MutableList的某些东西”。ArrayList关心对象的“结构”。它允许您直接操作对象分配的内存(trimToSize)。
  • 经验法则是,除非您确实关心底层结构的确切细节,否则应优先选择接口版本的内容(mutableListOf())。
  • 换句话说,如果您不知道要选择哪个,请首选mutableListOf()。

11

正如您在源代码中所看到的:

public inline fun <T> mutableListOf(): MutableList<T> = ArrayList()

所以,没有区别,只是一种方便的方法。


2
我会在“方便”上加引号。除非MutableList 实际上有不同的实现,否则提供一个与另一个核心对象执行相同操作的核心对象是令人困惑的,根本不方便。:( - Mike Williamson
1
@MikeWilliamson 因为数组列表是 Java 中最令人困惑的事情之一,对我来说它既是数组又是列表?我的脑子都快炸了。我觉得可变列表是这个奇怪类型的完美名称。 - t3chb0t

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接