代码之家  ›  专栏  ›  技术社区  ›  Elye

Kotlin:val mutableList与var immutableList。什么时候用哪个?

  •  2
  • Elye  · 技术社区  · 7 年前

    我们鼓励尽可能多地使用不可变变量。但如果我有时不得不修改列表,我想知道我应该使用哪种方法。。。

    1. val mutableList = mutableListOf() 在那里我可以 add , remove 因此

    1. var immutableList = listOf() 我将在其中创建一个新列表(使用filter或 + )每次做一个改变。

    我想有不同的情况,一个比另一个更受欢迎。因此想知道什么时候应该使用一个而不是另一个等等。

    3 回复  |  直到 7 年前
        1
  •  9
  •   Ramanathan Ganesan    7 年前

    可变和不可变列表增加了模型的设计清晰度。
    这是为了迫使开发商思考和明确收藏的目的。

    1. 如果集合将作为设计的一部分更改,请使用可变集合
    2. 如果模型仅用于查看,请使用不可变列表

    目的 val var 与不可变和可变列表不同。
    瓦尔 风险价值 关键字讨论如何处理变量的值/引用。

    • 风险价值 -分配给变量的值/引用可以在任何时间点更改。
    • 瓦尔 -值/引用只能分配给一个变量一次,以后在执行时不能更改。

    在Kotlin中,将可变列表赋给val并向其添加元素是完全有效的。

    val a = mutableListOf(1,2,3,4)
    a.add(5)
    println(a)
    

    将输出

    [1, 2, 3, 4, 5]
    
        2
  •  2
  •   Leon Chang    6 年前

    val->您可能认为 无法重新分配 对于变量。

    //that is ok
    var a:Int = 1
    a=2
    //Even you can reassign but you can't change its type
    a= "string"  //that's wrong
    
    //that is wrong
    val b:Int = 1
    b = 2
    

    列表->您可能认为 无法插入/删除/更改任何元素 在名单上 (无法对列表内容执行任何操作)

    var list:List<Int> = listOf(1,2,3,4) //[1,2,3,4]
    //you can read list
    list.get(0)
    list[0]
    //but you can't change(/write) the content of the list (insert/delete/alter)
    list.set(0, 100)
    list.add(5)
    list.removeAt(0)
    
    var mutableList:MutableList<Int> = mutableListOf(1,2,3,4) //[1,2,3,4]
    //you can read and write
    mutableList.get(0)
    mutableList.set(0, 100) //[100,2,3,4]
    mutableList.add(5)      //[100,2,3,4,5]
    mutableList.removeAt(0) //[2,3,4,5]
    

    所以 把它们结合起来,你会得到四个箱子

    案例1:var mutableList:mutableList=mutableListOf(1,2,3,4)

    //you can reassign 
    mutableList = mutableListOf(4,5,6,7) //[4,5,6,7]
    //you can alter the content 
    mutableList.set(0, 100) //[100,5,6,7]
    mutableList.add(8)      //[100,5,6,7,8]
    mutableList.removeAt(0) //[5,6,7,8]
    

    案例2:val mutableList:mutableList=mutableListOf(1,2,3,4)

    //you can't reassign 
    mutableList = mutableListOf(4,5,6,7) //that's wrong
    
    //you can alter the content 
    mutableList.set(0, 100) //[100,2,3,4]
    mutableList.add(8)      //[100,2,3,4,8]
    mutableList.removeAt(0) //[2,3,4,8]
    

    情况3:var list:list=ListOf(1,2,3,4)

    //you can reassign 
    list= ListOf(4,5,6,7) //[4,5,6,7]
    
    //you can't alter the content 
    list.set(0, 100) //that's wrong
    list.add(8)      //that's wrong
    list.removeAt(0) //that's wrong
    

    案例4:val list:list=列表(1,2,3,4)

    //you can't reassign 
    list= ListOf(4,5,6,7) //that's wrong
    
    //you can't alter the content 
    list.set(0, 100) //that's wrong
    list.add(8)      //that's wrong
    list.removeAt(0) //that's wrong
    
    //the only thing you can do is Read
    list.get(0)  //return 1
    list[0]      //return 1
    
        3
  •  0
  •   TheOperator    7 年前

    我想有不同的情况,一个比另一个更受欢迎。因此想知道什么时候应该使用一个而不是另一个等等。

    不可变对象通常更可取有以下几个原因:

    • 它们鼓励函数式编程,在这种编程中状态不会发生变化,而是传递给下一个基于它创建新状态的函数。这在Kotlin集合方法中非常明显,例如 map , filter , reduce 等等。
    • 没有副作用的程序通常更容易理解和调试(您可以确保对象的值始终是其定义的值)。
    • 在多线程程序中,不可变资源不会导致争用条件,因为不涉及写访问。

    你也有一些缺点:

    • 仅为添加/删除单个元素而复制整个集合在计算上非常昂贵。
    • 在某些情况下,当您单调地需要更改单个字段时,不变性会使代码更加复杂。在Kotlin中,数据类带有一个内置的 copy() 方法复制实例,同时仅为某些字段提供新值。

    最终使用哪一个取决于手头的用例。对于数据类(将几个属性捆绑在一起),坚持不变性通常是一个好主意。对于集合,如果使用不可变的集合只是为了修改它们的副本并始终重新分配指向它们的引用,那么也可以使用可变的集合。如果将集合共享到应用程序的许多依赖于状态保持不变的部分,请使用不可变。

    请记住,Kotlin系列有不同的概念:

    1. 可变集合: MutableList<T>, MutableSet<T>, MutableMap<T>
      这些可以随时修改。
    2. 只读集合: List<T>, Set<T>, Map<T>
      它们提供了 只读视图 在集合上,即集合不能被修改 通过引用 . 它不保证不可变性(它的另一个可变引用仍然可以存在并用于修改)。
    3. (提议,尚未成为科特林的一部分)
      不可变集合: ImmutableList<T>, ImmutableSet<T>, ImmutableMap<T>
      这将保证真正的不变性,并提供基于它们构建新的修改集合的模式。见 Proposal 详细情况。