ProgramaciónDesarrollador de Android

Describe el mecanismo de funcionamiento de las colecciones en Kotlin: diferencias entre List, MutableList, Set, MutableSet, Map, MutableMap. ¿Qué trampas pueden surgir al usarlas? Proporcione ejemplos de código.

Supere entrevistas con el asistente de IA Hintsage

Respuesta.

Kotlin ofrece dos tipos de colecciones: inmutables y mutables.

  • List — lista inmutable. No se pueden agregar o eliminar elementos.
  • MutableList — lista mutable: se pueden agregar y eliminar elementos.
  • Set — conjunto inmutable (elementos únicos).
  • MutableSet — conjunto mutable.
  • Map — mapa asociativo (clave-valor), inmutable.
  • MutableMap — mapa asociativo mutable.

Ejemplo de código:

val fruits: List<String> = listOf("Apple", "Banana", "Cherry") val mutableFruits: MutableList<String> = mutableListOf("Apple", "Banana") mutableFruits.add("Cherry") val fruitSet: Set<String> = setOf("Apple", "Banana") // Unicidad de elementos val mutableFruitSet: MutableSet<String> = mutableSetOf("Apple", "Banana") mutableFruitSet.add("Cherry") val scores: Map<String, Int> = mapOf("Tom" to 80, "Jane" to 90) val mutableScores: MutableMap<String, Int> = mutableMapOf("Tom" to 80) mutableScores["Jane"] = 90

Detalles:

  • Las colecciones son inmutables por defecto.
  • Muchas funciones que devuelven listas de la biblioteca estándar devuelven List (y no MutableList).
  • Al trabajar con colecciones, es importante no modificar aquellas que no están destinadas a ser modificadas.

Pregunta capciosa.

Si tienes una función que acepta List<T> como parámetro, ¿puedes de alguna manera modificar esta lista dentro de la función?

Respuesta: No, si el parámetro es del tipo List<T>, no se pueden agregar o eliminar elementos dentro de la función. Pero si de hecho se pasa un MutableList<T>, se puede convertir a este tipo (lo que conlleva un riesgo):

fun modifyList(list: List<String>) { if (list is MutableList) { list.add("Another") // Funciona si la colección original es mutable } }

No se recomienda hacer esto, ya que se viola el contrato (¡se debe considerar que List es inmutable!).

Ejemplos de errores reales debido a la falta de conocimiento sobre los detalles del tema.


Historia

En un gran proyecto se usó una función que aceptaba List<Customer>, y se intentó agregar un nuevo elemento dentro de la función. El error de compilación (add/clear/remove no se definen para List) solo se detectó durante la revisión, ya que se requería precisamente una lista mutable para transformar los datos.


Historia

La colección se declaró como MutableList, pero se pasó a varios hilos sin sincronización. Como resultado, surgieron cambios en competencia, lo que llevó a "ConcurrentModificationException" y a la corrupción del estado de la lista. Se tardó mucho en encontrar el error, ya que no se tuvo en cuenta la seguridad en hilos.


Historia

En uno de los servicios para trabajar con los resultados de las selecciones de la base de datos, se utilizó mutableListOf, luego se entregó el enlace hacia afuera. El código externo accidentalmente limpiaba la lista. Como resultado, se entregaban datos vacíos al usuario, ya que los enlaces no se clonaban y las colecciones mutables se modificaban fuera de la capa de lógica de negocio.