编程Android开发者

描述Kotlin中集合的工作机制:List、MutableList、Set、MutableSet、Map、MutableMap之间的差异。在使用时可能会遇到哪些潜在问题?请提供代码示例。

用 Hintsage AI 助手通过面试

答案。

Kotlin提供了两种类型的集合:不可变(immutable)可变(mutable)

  • List — 不可变列表。无法添加/删除元素。
  • MutableList — 可变列表:可以添加和删除元素。
  • Set — 不可变集合(唯一元素)。
  • MutableSet — 可变集合。
  • Map — 关联数组(键-值),不可变。
  • MutableMap — 可变关联数组。

代码示例:

val fruits: List<String> = listOf("Apple", "Banana", "Cherry") val mutableFruits: MutableList<String> = mutableListOf("Apple", "Banana") mutableFruits.add("Cherry") val fruitSet: Set<String> = setOf("Apple", "Banana") // 元素的唯一性 val mutableFruitSet: MutableSet<String> = mutableSetOf("Apple", "Banana") mutableFruitSet.add("Cherry") val scores: Map<String, Int> = mapOf("Tom" to 80, "Jane" to 90) val mutableScores: MutableMap<String, Int> = mutableMapOf("Tom" to 80) mutableScores["Jane"] = 90

细节:

  • 默认集合是不可变的。
  • 标准库中许多返回列表的函数返回List(而不是MutableList)。
  • 在处理集合时,重要的是不要修改那些不应改动的集合。

别出心裁的问题。

如果您有一个接受List<T>作为参数的函数,您能否在函数内部以某种方式修改该列表?

答案: 不可以,如果参数类型为List<T>,则在函数内部无法添加/删除元素。但是,如果实际上传递了MutableList<T>,则可以将其转换为该类型(这带来风险):

fun modifyList(list: List<String>) { if (list is MutableList) { list.add("Another") // 如果原始集合是可变的,则有效 } }

这样做不推荐,因为这违反了合同(List应为不可变的!)。

由于对主题细节不了解而导致的实际错误示例。


故事

在一个大型项目中,使用了一个接受List<Customer>的函数,并试图在函数内部添加新元素。编译错误(add/clear/remove未在List中定义)仅在审查时被发现,因为确实需要可变列表来转换数据。


故事

集合被声明为MutableList,但在多个线程中未同步传递。最终导致竞争性更改,导致"ConcurrentModificationException"和列表状态损坏。错误花了很长时间才找到,未考虑线程安全。


故事

在某个服务中,为处理数据库查询结果使用了mutableListOf,然后将引用外部传递。外部代码错误地清空了列表。结果,用户获取到空数据,因为引用未被克隆,并且可变集合在业务逻辑层之外被修改。