Stavo scrivendo un piccolo pezzo di codice in cui gestisco internamente i miei dati in una mappa mutabile, che a sua volta ha elenchi modificabili.Come trasformare una raccolta mutevole in una immutabile
Ho voluto esporre i miei dati all'utente API, ma per evitare pubblicazioni non sicure dei miei dati ho voluto esporlo in collezioni immutabili anche se internamente gestite da quelle mutevoli.
class School {
val roster: MutableMap<Int, MutableList<String>> = mutableMapOf<Int, MutableList<String>>()
fun add(name: String, grade: Int): Unit {
val students = roster.getOrPut(grade) { mutableListOf() }
if (!students.contains(name)) {
students.add(name)
}
}
fun sort(): Map<Int, List<String>> {
return db().mapValues { entry -> entry.value.sorted() }
.toSortedMap()
}
fun grade(grade: Int) = db().getOrElse(grade, { listOf() })
fun db(): Map<Int, List<String>> = roster //Uh oh!
}
sono riuscito a esporre solo Map
e List
(che sono immutabili) nella API pubblica della mia classe, ma le istanze realtà sto esponendo sono ancora intrinsecamente mutevole.
Ciò significa che un utente API può semplicemente trasmettere la mia mappa restituita come ImmutableMap e ottenere l'accesso ai preziosi dati privati interni alla mia classe, che doveva essere protetta da questo tipo di accesso.
Non sono riuscito a trovare un costruttore di copia nei metodi factory collection mutableMapOf()
o mutableListOf()
e quindi mi chiedevo quale sia il modo migliore e più efficiente per trasformare una raccolta mutabile in una immutabile.
Qualche consiglio o raccomandazione?
Una versione completa di questo è stata aggiunta a Klutter bloccando tutte le azioni correlate come un 'Iterator' ricevuto da una lista, una' sottoclasse' da una lista, un 'entrySet' da una mappa e altro. Vedi: http://stackoverflow.com/a/38002121/3679676 –