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,然后将引用外部传递。外部代码错误地清空了列表。结果,用户获取到空数据,因为引用未被克隆,并且可变集合在业务逻辑层之外被修改。