DartJuniorCoding

В чём разница между List, Set и Map в Dart?

List — упорядоченная последовательность с дубликатами и доступом по индексу; Set — уникальные элементы с быстрым contains; Map — пары ключ/значение с уникальными ключами и O(1) доступом.

List, Set и Map в Dart

Dart предоставляет три основные коллекции из core-библиотеки, каждая со своей семантикой хранения и доступа.

List — упорядоченная последовательность

List<T> хранит элементы в порядке добавления, допускает дубликаты и обеспечивает доступ по индексу за O(1). Это ближайший аналог массива или ArrayList.

final List<String> langs = ['Dart', 'Kotlin', 'Swift', 'Dart'];
print(langs[0]);          // Dart
print(langs.length);      // 4  (дубликат сохранён)
langs.add('Go');
langs.remove('Kotlin');
langs.sort();
print(langs);             // [Dart, Dart, Go, Swift]

Два варианта создания: List.filled(n, value) — фиксированного размера, [] — growable (по умолчанию).

Set — уникальные элементы без гарантии порядка

Set<T> гарантирует уникальность через хэш (реализация по умолчанию — LinkedHashSet, сохраняет порядок вставки). Проверка наличия элемента — O(1).

final Set<String> roles = {'admin', 'user', 'admin'};
print(roles);             // {admin, user}  — дубликат удалён
print(roles.contains('admin'));  // true

final a = {1, 2, 3};
final b = {2, 3, 4};
print(a.intersection(b)); // {2, 3}
print(a.union(b));        // {1, 2, 3, 4}
print(a.difference(b));   // {1}

Map — пары ключ-значение

Map<K, V> — ассоциативный массив. Ключи уникальны; по умолчанию используется LinkedHashMap, сохраняющий порядок вставки. Доступ за O(1).

final Map<String, int> scores = {'Alice': 95, 'Bob': 82};
scores['Carol'] = 91;
print(scores['Alice']);           // 95
print(scores['Unknown']);         // null
print(scores.containsKey('Bob')); // true

// Итерация
scores.forEach((name, score) {
  print('$name: $score');
});

// Безопасное обновление
scores.update('Bob', (v) => v + 5, ifAbsent: () => 0);

Сравнение по ключевым характеристикам

  • List: порядок гарантирован, дубликаты разрешены, доступ по индексу.
  • Set: только уникальные элементы, быстрая проверка contains, операции над множествами.
  • Map: поиск по ключу, уникальные ключи, значения могут повторяться.

const-коллекции

Все три типа поддерживают const — создание неизменяемых коллекций на этапе компиляции:

const list = [1, 2, 3];
const set  = {1, 2, 3};
const map  = {'a': 1};

Подводные камни

  • Пустой {} — это Map, а не Set. Dart выводит тип Map<dynamic, dynamic>, а не Set. Для пустого Set нужно явное <String>{} или Set<String>().
  • LinkedHashMap vs HashMap. Если порядок не важен и нужна максимальная скорость, явно используйте HashMap из dart:collection.
  • List фиксированного размера. List.filled(5, 0) бросает UnsupportedError на add(). Передайте growable: true если нужен рост.
  • Мутация во время итерации. Изменение List/Set внутри forEach или цикла for-in приводит к ConcurrentModificationError.
  • Equals/hashCode для Set и Map. Если используете собственный класс как ключ Map или элемент Set, необходимо переопределить == и hashCode, иначе сравнение идёт по идентичности объекта.
  • spread в Set с дубликатами не бросает исключение — дубликаты молча отбрасываются, что может маскировать логические ошибки.
  • Null-ключи и null-значения. Map допускает null в качестве ключа и значения; обращение map['key'] возвращает null как для отсутствующего ключа, так и для явно сохранённого null — используйте containsKey для разграничения.

Common mistakes

  • Сводить «List, Set и Map в Dart» к синтаксису и не объяснять sound type system.
  • Игнорировать жизненный цикл, основной поток или момент освобождения ресурсов в сценарии dart-20.
  • Выбирать API по привычке, не проверяя состояние, ошибки, доступность и платформенные ограничения.

What the interviewer is testing

  • Формулирует точную модель для «List, Set и Map в Dart» и подтверждает ее корректным примером.
  • Умеет связать ответ с event loop, тестированием и отладкой на устройстве.
  • Называет ограничения подхода dart-20, включая производительность, память и сопровождение.

Sources

Related topics