Kotlin 的列表缺少"add"、"remove"、地图缺少"put"等?



在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)
}
}

我收到错误,无法从我的列表中找到addremove函数

我致力于将其转换为 ArrayList,但这很奇怪,需要强制转换它,而在 Java 中不需要转换。这违背了拥有抽象类列表的目的

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 中定义列表集合:

具有不可变
  • (只读)列表的不可变变量:

    val users: List<User> = listOf( User("Tom", 32), User("John", 64) )
    


  • 具有可变列表的不可变变量:

    val users: MutableList<User> = mutableListOf( User("Tom", 32), User("John", 64) )
    

    或没有初始值 - 空列表和没有显式变量类型:

    val users = mutableListOf<User>()
    //or
    val users = ArrayList<User>()
    
    • 您可以将项目添加到列表:
      • users.add(anohterUser)
      • users += anotherUser(引擎盖下是users.add(anohterUser))


  • 具有不可变列表的可变变量:

    var users: List<User> = listOf( User("Tom", 32), User("John", 64) )
    

    或没有初始值 - 空列表和没有显式变量类型:

    var users = emptyList<User>()
    
    • 注意:您可以将*项添加到列表中:
      • users += anotherUser- *它创建新的 ArrayList 并将其分配给users


  • 具有可变列表的可变变量:

    var users: MutableList<User> = mutableListOf( User("Tom", 32), User("John", 64) )
    

    或没有初始值 - 空列表和没有显式变量类型:

    var users = emptyList<User>().toMutableList()
    //or
    var users = ArrayList<User>()
    
    • 注意:您可以将项目添加到列表:
      • users.add(anohterUser)
      • 但不使用users += anotherUser

        错误:Kotlin:赋值运算符歧义:
        公共运算符乐趣 Collection.plus(元素:字符串):在 kotlin.collections 中定义的列表 @InlineOnly 公共内联运算符乐趣 MutableCollection.plusAssign(元素:字符串):在 kotlin.collections
        中定义的单位


另请参阅: https://kotlinlang.org/docs/reference/collections.html

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

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

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

显然,默认的 Kotlin 列表是不可变的。 要有一个可以更改的列表,应该使用可变列表,如下所示

class TempClass {
var myList: MutableList<Int>? = null
fun doSomething() {
myList = ArrayList<Int>()
myList!!.add(10)
myList!!.remove(10)
}
}

已更新尽管如此,不建议使用 MutableList,除非您确实想要更改列表。参考只读集合如何提供更好的编码 https://hackernoon.com/read-only-collection-in-kotlin-leads-to-better-coding-40cdfa4c6359。

在 Kotlin 中,您必须使用MutableListArrayList

让我们看看MutableList的方法是如何工作的:

var listNumbers: MutableList<Int> = mutableListOf(10, 15, 20)
// Result: 10, 15, 20
listNumbers.add(1000)
// Result: 10, 15, 20, 1000
listNumbers.add(1, 250)
// Result: 10, 250, 15, 20, 1000
listNumbers.removeAt(0)
// Result: 250, 15, 20, 1000
listNumbers.remove(20)
// Result: 250, 15, 1000
for (i in listNumbers) { 
println(i) 
}

让我们看看ArrayList的方法是如何工作的:

var arrayNumbers: ArrayList<Int> = arrayListOf(1, 2, 3, 4, 5)
// Result: 1, 2, 3, 4, 5
arrayNumbers.add(20)
// Result: 1, 2, 3, 4, 5, 20
arrayNumbers.remove(1)
// Result: 2, 3, 4, 5, 20
arrayNumbers.clear()
// Result: Empty
for (j in arrayNumbers) { 
println(j) 
}

更新:从 Kotlin 1.3.70 开始,下面的确切buildList函数作为实验函数在标准库中提供,以及它的类似物buildSetbuildMap.请参阅 https://blog.jetbrains.com/kotlin/2020/03/kotlin-1-3-70-released/。

将可变性限制在构建者身上

这里的顶级答案正确地说明了 Kotlin 中只读List(注意:它是只读的,而不是"不可变的")和MutableList之间的区别。

一般来说,应该努力使用只读列表,但是,可变性在构造时仍然经常有用,尤其是在处理具有非功能接口的第三方库时。对于没有替代构造技术的情况,例如直接使用listOf,或应用函数构造(如foldreduce),像下面这样的简单"构建器函数"构造可以从临时可变列表生成只读列表:

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")
}

现在,所有可变性都隔离到用于构造只读列表的一个块作用域,其余代码使用生成器输出的只读列表。

你可以像这样创建一个新的。

var list1 = ArrayList<Int>()
var list2  = list1.toMutableList()
list2.add(item)

现在您可以使用list2,谢谢。

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

根据上面的链接 List在 Kotlin 中是不可变的。 但是这将起作用:

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

listDefaultimmutable,您可以改用ArrayList。 像这样:

val orders = arrayListOf<String>()

然后,您可以从中add/delete项目,如下所示:

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

默认情况下,ArrayListmutable,因此您可以对其执行操作。

在不可变数据的概念中,也许这是一个更好的方法:

class TempClass {
val list: List<Int> by lazy {
listOf<Int>()
}
fun doSomething() {
list += 10
list -= 10
}
}

最新更新