How to turn a Mutable Collection into an Immutable one

后端 未结 6 1032
醉话见心
醉话见心 2020-12-14 14:52

I was writing a small piece of code in which I internally handle my data in a mutable map, which in turn has mutable lists.

I wanted to expose my data to the API use

6条回答
  •  眼角桃花
    2020-12-14 15:34

    Currently in Kotlin stdlib there are no implementations of List (Map) that would not also implement MutableList (MutableMap). However due to Kotlin's delegation feature the implementations become one liners:

    class ImmutableList(private val inner:List) : List by inner
    class ImmutableMap(private val inner: Map) : Map by inner
    

    You can also enhance the creation of the immutable counterparts with extension methods:

    fun  Map.toImmutableMap(): Map {
        if (this is ImmutableMap) {
            return this
        } else {
            return ImmutableMap(this)
        }
    }
    
    fun  List.toImmutableList(): List {
        if (this is ImmutableList) {
            return this
        } else {
            return ImmutableList(this)
        }
    }
    

    The above prevents a caller from modifying the List (Map) by casting to a different class. However there are still reasons to create a copy of the original container to prevent subtle issues like ConcurrentModificationException:

    class ImmutableList private constructor(private val inner: List) : List by inner {
        companion object {
            fun  create(inner: List) = if (inner is ImmutableList) {
                    inner
                } else {
                    ImmutableList(inner.toList())
                }
        }
    }
    
    class ImmutableMap private constructor(private val inner: Map) : Map by inner {
        companion object {
            fun  create(inner: Map) = if (inner is ImmutableMap) {
                inner
            } else {
                ImmutableMap(hashMapOf(*inner.toList().toTypedArray()))
            }
        }
    }
    
    fun  Map.toImmutableMap(): Map = ImmutableMap.create(this)
    fun  List.toImmutableList(): List = ImmutableList.create(this)
    

    While the above is not hard to implement there are already implementations of immutable lists and maps in both Guava and Eclipse-Collections.

提交回复
热议问题