在Java中,我们可以这样做
public class TempClass {
List<Integer> myList = null;
void doSomething() {
myList = new ArrayList<>();
myList.add(10);
myList.remove(10);
}
}
但如果我们直接重写给Kotlin,如下所示
class TempClass {
var myList: List<Int>? = null
fun doSomething() {
myList = ArrayList<Int>()
myList!!.add(10)
myList!!.remove(10)
}
}
我得到的错误,没有找到添加和删除函数从我的列表
我把它强制转换为数组列表,但强制转换是奇怪的,而在Java中,强制转换是不需要的。这就违背了使用抽象类List的目的
class TempClass {
var myList: List<Int>? = null
fun doSomething() {
myList = ArrayList<Int>()
(myList!! as ArrayList).add(10)
(myList!! as ArrayList).remove(10)
}
}
是否有一种方法可以让我使用List但不需要强制转换,就像在Java中可以做的那样?
更新:从Kotlin 1.3.70开始,下面的buildList函数可以作为实验函数在标准库中使用,它还有类似的buildSet和buildMap。见https://blog.jetbrains.com/kotlin/2020/03/kotlin - 1 - 3 - 70 - released/。
将可变性限制到构建器
上面的答案正确地说明了Kotlin中只读列表(注意:它是只读的,不是“不可变的”)和MutableList之间的区别。
一般来说,应该尽量使用只读列表,但是,在构造时,可变性仍然很有用,特别是在处理具有非函数接口的第三方库时。对于无法使用其他构造技术的情况,比如直接使用listOf,或者应用像fold或reduce这样的函数式构造,像下面这样简单的“构造器函数”构造可以很好地从临时可变列表生成只读列表:
val readonlyList = mutableListOf<...>().apply {
// manipulate your list here using whatever logic you need
// the `apply` function sets `this` to the `MutableList`
add(foo1)
addAll(foos)
// etc.
}.toList()
这可以很好地封装到一个可重用的内联实用函数中:
inline fun <T> buildList(block: MutableList<T>.() -> Unit) =
mutableListOf<T>().apply(block).toList()
可以这样称呼:
val readonlyList = buildList<String> {
add("foo")
add("bar")
}
现在,所有的可变性都被隔离到一个用于构造只读列表的块范围中,其余代码使用从构建器输出的只读列表。
更新:从Kotlin 1.3.70开始,下面的buildList函数可以作为实验函数在标准库中使用,它还有类似的buildSet和buildMap。见https://blog.jetbrains.com/kotlin/2020/03/kotlin - 1 - 3 - 70 - released/。
将可变性限制到构建器
上面的答案正确地说明了Kotlin中只读列表(注意:它是只读的,不是“不可变的”)和MutableList之间的区别。
一般来说,应该尽量使用只读列表,但是,在构造时,可变性仍然很有用,特别是在处理具有非函数接口的第三方库时。对于无法使用其他构造技术的情况,比如直接使用listOf,或者应用像fold或reduce这样的函数式构造,像下面这样简单的“构造器函数”构造可以很好地从临时可变列表生成只读列表:
val readonlyList = mutableListOf<...>().apply {
// manipulate your list here using whatever logic you need
// the `apply` function sets `this` to the `MutableList`
add(foo1)
addAll(foos)
// etc.
}.toList()
这可以很好地封装到一个可重用的内联实用函数中:
inline fun <T> buildList(block: MutableList<T>.() -> Unit) =
mutableListOf<T>().apply(block).toList()
可以这样称呼:
val readonlyList = buildList<String> {
add("foo")
add("bar")
}
现在,所有的可变性都被隔离到一个用于构造只读列表的块范围中,其余代码使用从构建器输出的只读列表。
与许多语言不同,Kotlin区分了可变和不可变集合(列表、集、映射等)。精确控制何时可以编辑集合对于消除错误和设计好的api很有用。
https://kotlinlang.org/docs/reference/collections.html
您需要使用MutableList列表。
class TempClass {
var myList: MutableList<Int> = mutableListOf<Int>()
fun doSomething() {
// myList = ArrayList<Int>() // initializer is redundant
myList.add(10)
myList.remove(10)
}
}
MutableList<Int> = arrayListOf()也应该工作。