Search code examples
kotlinconstructorcastingdelegation

How to cast the List received in the primary constructor to MutableList so that we can delegate the class to MutableList


I want to implement the kotlin's MutableList interface by adding some thread safe features and if i want to implement MutableList interface and overriding only the stuffs which are unsafe for thread, hence I choosen delegation.

Every time using List.toMutableList() it returns a new Instance of MutableList containing all the items in data.

class ThreadSafeList<E> constructor(data: List<E>): MutableList<E> by data.toMutableList() //different reference (new object created when using toMutableList())
{
    private val data = data.toMutableList() //different reference (new object created when using toMutableList())
    ...

    //default constructor when no argument is supplied
    constructor(): this(listOf())

    //override, locks & stuffs for thread safety
}

Expectation: I want to cast List to MutableList in constructor itself so that the implementation delegate holds for the same reference as the val data holds, but I am unable to find how to do so.


Solution

  • After a lot of research I finally found a way to do it.

    I'll explain how i did so, It might help anybody suffering from this problem,

    class ThreadSafeList<E> private constructor(private val data: MutableList<E>): MutableList<E> by data
    {
        // default constructor, when no elements are passed
        constructor(): this(mutableListOf())
    
        companion object {
            // constructor for a list to use its elements for the purpose
            operator fun <E> invoke(elements: List<E>): ThreadSafeList<E>
            {
                return ThreadSafeList(elements.toMutableList())
            }
        }
    }
    
    
    fun main()
    {
        // this is how you call it
        val list = listOf("Hello", "World", "!")
        val threadSafeList = threadSafeListOf(list)
    }
    

    Here what I've done is maybe a hack but it works like a charm. This is why I love kotlin.

    You can create the object as you usually do, the in invoke fun is also not required to put in when creating the object as it is auto-done by kotlin compiler when passing a list to it.