如何使用Kotlin样式向CopyInWriteCollection添加元素?

时间:2019-06-20 11:06:35

标签: kotlin collections immutability immutable-collections

假设我们有一个自定义集合

class CopyOnWriteCollection<T> {

   // returns copy of collection with new element
   fun add(element: T): CopyOnWriteCollection<T> {
    ...
   }
}

如果我需要添加几个元素,我会做这样的事情:

val newCollection = oldCollection
    .add(1)
    .add(2)
    .add(3)

并且newCollection包含oldCollection中的元素,并且还包含1,2,3。 完美!

但是如何使用forEach中的map从另一个集合中添加元素?

val collection = CopyOnWriteCollection()
(1..3).forEach { collection.add(it) } // this approach works only with mutable collections

2 个答案:

答案 0 :(得分:2)

您可以使用命令式循环,也可以使用fold()函数:

fun main() {
    var collection = CopyOnWriteCollection<Int>()
    var collection2 = collection

    for (i in 1..3) {
        collection = collection.add(i)
    }

    println(collection)

    collection2 = (1..3).fold(collection2) { coll, i -> coll.add(i) }
    println(collection2)
}

class CopyOnWriteCollection<T> {

    private val list = mutableListOf<T>()

    // returns copy of collection with new element
    fun add(element: T): CopyOnWriteCollection<T> {
        val copy = CopyOnWriteCollection<T>()
        copy.list.addAll(this.list)
        copy.list.add(element)
        return copy;
    }

    override fun toString() = list.toString()
}

答案 1 :(得分:0)

如果CopyOnWriteCollection类在您的控制之下,我可以通过向其添加一个addAll()方法来实现:

    /** Returns copy of collection with new element. */
    fun addAll(elements: Collection<T>): CopyOnWriteCollection<T> {
        // ...
    }

然后您可以使用例如

进行呼叫
val newCollection = oldCollection.addAll(listOf(1, 2, 3))

(或者您可以使用vararg而不是集合。)

这可能会花费更少的时间和内存。

(此外,如果您确实需要编写自己的集合类,我强烈建议您实现Collection(或在适当时使用其子接口之一),或扩展一个可以这样做的类。 stdlib中的扩展方法和其他优点种类繁多。)