Я писал небольшой фрагмент кода, в котором я внутренне обрабатываю свои данные на изменяемой карте, которая, в свою очередь, имеет изменяемые списки.
Я хотел выставить свои данные пользователю API, но чтобы избежать какой-либо небезопасной публикации моих данных, я хотел разоблачить ее в неизменяемых коллекциях, даже когда внутренне обрабатываются изменчивыми.
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!
}
Мне удалось отобразить только public Map
и List
(которые являются неизменяемыми) в публичном API моего класса, но экземпляры, которые я фактически просматриваю, по-прежнему по своей сути изменяемы.
Это означает, что пользователь API может просто передать мою возвращенную карту как ImmutableMap и получить доступ к ценным личным данным, внутренним для моего класса, который должен был быть защищен от такого доступа.
Я не смог найти конструктор копирования в методах коллекции factory mutableMapOf()
или mutableListOf()
, и поэтому мне было интересно, что является лучшим и наиболее эффективным способом превратить изменчивую коллекцию в неизменяемую.
Любые советы или рекомендации?