在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区分了可变和不可变集合(列表、集、映射等)。精确控制何时可以编辑集合对于消除错误和设计好的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()也应该工作。

其他回答

在Kotlin中以不同的方式定义List集合:

Immutable variable with immutable (read only) list: val users: List<User> = listOf( User("Tom", 32), User("John", 64) ) Immutable variable with mutable list: val users: MutableList<User> = mutableListOf( User("Tom", 32), User("John", 64) ) or without initial value - empty list and without explicit variable type: val users = mutableListOf<User>() //or val users = ArrayList<User>() you can add items to list: users.add(anohterUser) or users += anotherUser (under the hood it's users.add(anohterUser))

可变变量与不可变列表: var users: List<User> = listOf(User("Tom", 32), User("John", 64)) 或者没有初始值-空列表且没有显式变量类型: var users = emptyList<用户>() 注意:您可以在列表中添加*项: users += anotherUser - *它创建一个新的数组列表并将其分配给用户

Mutable variable with mutable list: var users: MutableList<User> = mutableListOf( User("Tom", 32), User("John", 64) ) or without initial value - empty list and without explicit variable type: var users = emptyList<User>().toMutableList() //or var users = ArrayList<User>() NOTE: you can add items to list: users.add(anohterUser) but not using users += anotherUser Error: Kotlin: Assignment operators ambiguity: public operator fun Collection.plus(element: String): List defined in kotlin.collections @InlineOnly public inline operator fun MutableCollection.plusAssign(element: String): Unit defined in kotlin.collections

参见: https://kotlinlang.org/docs/reference/collections.html

更新:从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")
}

现在,所有的可变性都被隔离到一个用于构造只读列表的块范围中,其余代码使用从构建器输出的只读列表。

默认情况下,列表是不可变的,您可以使用ArrayList代替。像这样:

 val orders = arrayListOf<String>()

然后你可以像下面这样添加/删除项目:

orders.add("Item 1")
orders.add("Item 2")

默认情况下,ArrayList是可变的,所以你可以对它执行操作。

https://kotlinlang.org/docs/reference/collections.html

根据上面的链接列表<E>在Kotlin中是不可变的。 然而,这是可行的:

var list2 = ArrayList<String>()
list2.removeAt(1)

同意以上所有使用MutableList的答案,但你也可以从列表中添加/删除,并获得如下所示的新列表。

val newListWithElement = existingList + listOf(element)
val newListMinusElement = existingList - listOf(element)

Or

val newListWithElement = existingList.plus(element)
val newListMinusElement = existingList.minus(element)