Bukharov Sergey
Bukharov Sergey

Reputation: 10185

How to add elements to CopyInWriteCollection using Kotlin style?

Assume we have a custom collection

class CopyOnWriteCollection<T> {

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

if i need to add several elements i would do something like this:

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

And newCollection contains elements from oldCollection and also contains 1,2,3. Perfect!

But how can i add elements from another collection using forEach of map?

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

Upvotes: 0

Views: 36

Answers (2)

gidds
gidds

Reputation: 18597

If the CopyOnWriteCollection class is under your control, I'd approach this by adding an addAll() method to it:

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

You could then call that with e.g.

val newCollection = oldCollection.addAll(listOf(1, 2, 3))

(Or you could take a vararg instead of a collection.)

That's likely to take a lot less time and memory.

(Also, if you really need to write your own collection class, I'd strongly recommend implementing Collection (or one of its subinterfaces if appropriate), or extending a class which does.  That will give access to the huge range of extension methods and other goodies in the stdlib.)

Upvotes: 0

JB Nizet
JB Nizet

Reputation: 691913

You can use an imperative loop, or you can use the fold()function:

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

Upvotes: 2

Related Questions