Saltar al contenido

Cómo convertir una colección mutable en una inmutable

Solución:

Actualmente en Kotlin stdlib no hay implementaciones de List<T> (Map<K,V>) ese no implementaría también MutableList<T> (MutableMap<K,V>). Sin embargo, debido a la función de delegación de Kotlin, las implementaciones se convierten en una sola línea:

class ImmutableList<T>(private val inner:List<T>) : List<T> by inner
class ImmutableMap<K, V>(private val inner: Map<K, V>) : Map<K, V> by inner

También puede mejorar la creación de contrapartes inmutables con métodos de extensión:

fun <K, V> Map<K, V>.toImmutableMap(): Map<K, V> {
    if (this is ImmutableMap<K, V>) {
        return this
    } else {
        return ImmutableMap(this)
    }
}

fun <T> List<T>.toImmutableList(): List<T> {
    if (this is ImmutableList<T>) {
        return this
    } else {
        return ImmutableList(this)
    }
}

Lo anterior evita que una persona que llama modifique el List (Map) enviando a una clase diferente. Sin embargo, todavía hay razones para crear una copia del contenedor original para evitar problemas sutiles como ConcurrentModificationException:

class ImmutableList<T> private constructor(private val inner: List<T>) : List<T> by inner {
    companion object {
        fun <T> create(inner: List<T>) = if (inner is ImmutableList<T>) {
                inner
            } else {
                ImmutableList(inner.toList())
            }
    }
}

class ImmutableMap<K, V> private constructor(private val inner: Map<K, V>) : Map<K, V> by inner {
    companion object {
        fun <K, V> create(inner: Map<K, V>) = if (inner is ImmutableMap<K, V>) {
            inner
        } else {
            ImmutableMap(hashMapOf(*inner.toList().toTypedArray()))
        }
    }
}

fun <K, V> Map<K, V>.toImmutableMap(): Map<K, V> = ImmutableMap.create(this)
fun <T> List<T>.toImmutableList(): List<T> = ImmutableList.create(this)

Si bien lo anterior no es difícil de implementar, ya existen implementaciones de listas y mapas inmutables en las colecciones de Guava y Eclipse.

Usar Colecciones convertir un Mudable lista para Inmutable lista, Ejemplo:

Lista mutable:

val mutableList = mutableListOf<String>()

Convierte a lista inmutable:

val immutableList = Collections.unmodifiableList(mutableList)

Como se mencionó aquí y aquí, necesitaría escribir su propio List implementación para eso, o use una existente (ImmutableList de Guava me viene a la mente, o Eclipse Collections como sugirió Andrew).

Kotlin aplica la (im) mutabilidad de la lista solo por interfaz. No existen List implementaciones que tampoco implementan MutableList.

Incluso el idiomático listOf(1,2,3) termina llamando a Kotlin’s ArraysUtilJVM.asList() que llama a Java Arrays.asList() que devuelve un Java antiguo simple ArrayList.

Si le importa más proteger su propia lista interna que la inmutabilidad en sí, puede, por supuesto, copiar la colección completa y devolverla como un List, al igual que hace Kotlin:

return ArrayList(original)
¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)


Tags : /

Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *