Могут ли элементы потеряться в HashMap
Что проверяют
Понимаете ли вы, при каких условиях из HashMap пропадают данные в Android-приложении: из-за ключей, потоков или жизненного цикла процесса. Следом часто спрашивают про data class в роли ключа и про корутины.
Как отвечать
В Kotlin на Android HashMap и mutableMapOf() это обычные JVM-коллекции (mutableMapOf() возвращает LinkedHashMap), и сами по себе записи они не теряют. Причины практические:
- изменяемый ключ:
data classгенерируетhashCode()из свойств основного конструктора. Если там естьvarи его поменяли послеput(), запись остаётся в старой корзине,map[key]возвращаетnull, а элемент продолжает висеть в карте. Ключи держите наvalи неизменяемых типах; - ключ без
hashCode(): обычный класс, где переопределён толькоequals(), даёт дубли и промахи; - гонки: карту наполняют из
Dispatchers.IO, а читают на главном потоке. Без синхронизации одновременныеput()затирают друг друга. Варианты:ConcurrentHashMap,Mutexиз kotlinx.coroutines вокруг изменений или работа с картой в одном потоке черезlimitedParallelism(1); - смерть процесса: система убивает фоновое приложение, и кэш в
HashMapвнутри синглтона илиViewModelисчезает. Это не баг карты, но «потеря» на практике чаще всего именно она. То, что должно пережить смерть процесса, хранят вSavedStateHandle, DataStore или Room.
Для кэшей упомяните LruCache с ограничением размера: HashMap без вытеснения на долгоживущем объекте постепенно съедает память и приводит к OutOfMemoryError. Для небольших карт есть ArrayMap и SparseArray (в том числе в androidx.collection): они экономят память, но от перечисленных проблем не спасают.
Где спотыкаются
Говорят, что сборщик мусора может удалить запись из HashMap. Это поведение WeakHashMap, обычная карта держит ключи сильными ссылками.
Кладут в ключ data class с var, например модель из сети, и потом меняют её поле. Ошибка тихая: исключения нет, просто пропадает значение.
Оборачивают в synchronized только запись, а чтение оставляют как есть. Без синхронизации чтения нет гарантии видимости, и главный поток может увидеть карту в промежуточном состоянии.