Una colección es una estructura que nos permite agrupar varios datos bajo una misma variable.
En el mundo real, los datos rara vez vienen solos. Los usuarios vienen en listas, las configuraciones en diccionarios y las categorías en grupos. Para manejar esto, Dart nos ofrece las Colecciones.
Si vienes de JavaScript, esto te resultará familiar, pero ojo: en Dart las colecciones son tipadas. Es decir, no mezclamos peras con manzanas (a menos que nosotros queramos explícitamente).
Hoy vamos a ver los tres tipos principales: List, Set y Map, y cómo operar con ellos de forma elegante.
Listas (List)
La lista es una colección ordenada de elementos. Es el equivalente a los Arrays en otros lenguajes. Se denotan con corchetes [].
Declaración y tipado
Podemos dejar que Dart infiera el tipo o especificarlo nosotros usando “Generics” (los símbolos < >).
// Inferencia: Dart sabe que es List<int>
var numeros = [1, 2, 3, 4, 5];
// Tipado explícito: Solo permitimos Strings
List<String> nombres = ["Ana", "Luis", "Carlos"];
// numeros.add("Texto"); // ❌ Error: No puedes meter texto en lista de enteros
Acceso y modificación
Como son ordenadas, accedemos a sus elementos por su índice (empezando en 0).
var frutas = ["Manzana", "Pera"];
print(frutas[0]); // Manzana
frutas.add("Plátano"); // Añade al final
print(frutas.length); // 3
En Flutter usarás List constantemente. Por ejemplo, una Column o un ListView reciben una List<Widget> como hijos.
Sets (Set)
Un Set es una colección de elementos únicos y sin acceso por índice. Se denota con llaves { }. El Set creado por defecto conserva el orden de inserción al iterarlo, aunque no conviene usarlo como sustituto de una lista.
La principal diferencia con la lista es que no permite duplicados. Si intentas añadir algo que ya existe, simplemente lo ignora.
Set<String> paises = {"España", "Francia", "Italia"};
paises.add("España"); // No hace nada, ya existe.
print(paises); // {España, Francia, Italia}
Son muy útiles para filtrar duplicados de una lista o para comprobaciones rápidas de existencia.
Mapas (Map)
El Map es un diccionario. Relaciona una Clave (Key) con un Valor (Value). Es la estructura que usamos para representar objetos JSON.
Se define también con llaves {}, pero diferenciamos que es un mapa porque tiene la estructura clave: valor.
// Map<String, dynamic>
// String para la clave, dynamic para el valor (porque puede ser texto, numero, etc.)
Map<String, dynamic> usuario = {
"nombre": "Luis",
"edad": 30,
"esAdmin": true
};
Acceso a datos
Accedemos usando la clave entre corchetes, similar a una lista, pero usando el nombre de la clave.
print(usuario["nombre"]); // Luis
// Asignar nuevo valor
usuario["edad"] = 31;
El tipo Map<String, dynamic> aparece muchísimo en Flutter para procesar datos que vienen de una API REST o Firebase.
Operador spread ...
Una pequeña joya de Dart moderno que usarás mucho en interfaces de usuario es el Spread Operator (tres puntos ...). Sirve para “esparcir” los elementos de una lista dentro de otra.
var primeraFase = ["Boceto", "Diseño"];
var segundaFase = ["Desarrollo", "Test"];
var proyectoCompleto = [
...primeraFase, // Inserta los elementos aquí
...segundaFase,
"Despliegue"
];
// Resultado: [Boceto, Diseño, Desarrollo, Test, Despliegue]
Métodos funcionales: .map() y .where()
Aquí es donde pasamos de “saber programar” a “programar como un pro”.
En lugar de usar bucles for para transformar listas, en Dart usamos métodos funcionales. Esto es crítico en Flutter, donde a menudo querrás transformar una Lista de Datos en una Lista de Widgets.
.map() para transformar
Recorre la lista, ejecuta una función para cada elemento y devuelve una nueva colección con los resultados transformados.
var numeros = [1, 2, 3, 4, 5];
// Queremos el doble de cada número
var dobles = numeros.map((n) {
return n * 2;
}).toList(); // ⚠️ Importante: .map devuelve un Iterable, hay que convertirlo a Lista
print(dobles); // [2, 4, 6, 8, 10]
O usando funciones flecha (más limpio):
var dobles = numeros.map((n) => n * 2).toList();
.where() para filtrar
Devuelve una nueva colección solo con los elementos que cumplan una condición (devuelvan true).
var numeros = [1, 2, 3, 4, 5, 6];
// Solo los pares
var pares = numeros.where((n) => n % 2 == 0).toList();
print(pares); // [2, 4, 6]
Iterables y listas
Un detalle técnico que suele confundir: métodos como map o where no devuelven una List, sino un Iterable.
Un Iterable es una colección que se evalúa de forma perezosa (lazy). Por eso, casi siempre al final de estas operaciones encadenamos un .toList() para materializar los datos y poder usarlos en nuestra UI.