Defensive copy of volatile collection in Kotlin data class

I want the data class to accept a read-only list:

data class Notebook(val notes: List<String>) {
}

But he can also accept MutableList, because it is a subtype List.

For example, the following code modifies the past in a list:

fun main(args: Array<String>) {
    val notes = arrayListOf("One", "Two")
    val notebook = Notebook(notes)

    notes.add("Three")

    println(notebook)       // prints: Notebook(notes=[One, Two, Three])
}

Is there a way to make a protected copy of the passed data class in the list?

+4
source share
3 answers

I think it's better to use the JetBrains library for immutable collections - https://github.com/Kotlin/kotlinx.collections.immutable

Import to project

Add the bintray repository:

repositories {
    maven {
        url "http://dl.bintray.com/kotlin/kotlinx"
    }
}

Add dependency:

compile 'org.jetbrains.kotlinx:kotlinx-collections-immutable:0.1'

Result:

data class Notebook(val notes: ImmutableList<String>) {}

fun main(args: Array<String>) {
    val notes = immutableListOf("One", "Two")
    val notebook = Notebook(notes)

    notes.add("Three") // creates a new collection

    println(notebook)       // prints: Notebook(notes=[One, Two])
}

: ImmutableList, , .

+1

1

.toList(), , , , .

:

data class Notebook(private val _notes: List<String>) {
    val notes: List<String> = _notes.toList()
}

, .equals() .hashCode() .

, :

class Notebook(notes: List<String>) {
    val notes: List<String> = notes.toList()
}

2

Kotlin , , : https://github.com/Kotlin/kotlinx.collections.immutable


3

- , MutableList. , Klutter, , , . , . , . , . . Clutter ReadOnly Collection Wrappers .

Klutter :

data class Notebook(val notes: ReadOnlyList<String>) {

, , :

val myList = mutableListOf("day", "night")
Notebook(myList.toImmutable())  // copy and protect

, , ( asReadOnly()) , - , .

Klutter , ReadOnly vs. Immutable, , asReadOnly(), - . ( Klutter) , factory - (.. internal). , , . - , asReadOnly(), toImmutable() internal.

</" >

. : ?

+3

, . , , .

class Notebook(notes: List<String>) {
    val notes: List<String> = notes.toList()
}

, , , - init , var, , , .

data class Notebook(var notes: List<String>) {
    init {
        notes = notes.toList()
    }
}
0

Source: https://habr.com/ru/post/1678785/


All Articles