Что такое Set в Dart и как он используется?

«Что такое Set в Dart и как он используется?» — вопрос из категории Dart Core, который задают на 29% собеседований Flutter Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Set в Dart — это неупорядоченная коллекция уникальных элементов. В отличие от List, Set гарантирует уникальность элементов и обеспечивает быстрый поиск (O(1) в среднем случае).

Основные характеристики:

  • Все элементы уникальны (дубликаты игнорируются)
  • Порядок не гарантируется (кроме LinkedHashSet)
  • Быстрые операции contains(), add(), remove()

Создание Set:

// Set-литерал
Set<String> fruits = {'apple', 'banana', 'orange'};

// Конструктор
Set<int> numbers = Set();
numbers.addAll([1, 2, 3, 3, 2, 1]); // Результат: {1, 2, 3}

// Из другого Iterable
Set<String> uniqueNames = Set.from(['Alice', 'Bob', 'Alice']);
print(uniqueNames); // {Alice, Bob}

Типы Set в Dart:

  1. HashSet (по умолчанию):

    final hashSet = HashSet<int>();
    // Быстрый доступ, порядок не сохраняется
  2. LinkedHashSet (сохраняет порядок вставки):

    final orderedSet = LinkedHashSet<String>();
    orderedSet.addAll(['z', 'a', 'b']);
    print(orderedSet); // {z, a, b} - порядок сохранен
  3. SplayTreeSet (отсортированный):

    final sortedSet = SplayTreeSet<int>((a, b) => b.compareTo(a));
    sortedSet.addAll([3, 1, 4, 1, 5]);
    print(sortedSet); // {5, 4, 3, 1} - отсортировано по убыванию

Полезные операции:

final setA = {1, 2, 3, 4};
final setB = {3, 4, 5, 6};

// Объединение
print(setA.union(setB)); // {1, 2, 3, 4, 5, 6}

// Пересечение
print(setA.intersection(setB)); // {3, 4}

// Разность
print(setA.difference(setB)); // {1, 2}

// Проверка подмножества
print({1, 2}.isSubsetOf(setA)); // true

Практическое использование в Flutter:

// Уникальные ID выбранных элементов
Set<String> selectedIds = {};

void toggleSelection(String id) {
  if (selectedIds.contains(id)) {
    selectedIds.remove(id);
  } else {
    selectedIds.add(id);
  }
  setState(() {});
}

// Фильтрация дубликатов в списке
List<Product> removeDuplicates(List<Product> products) {
  final uniqueIds = Set<String>();
  return products.where((product) {
    return uniqueIds.add(product.id); // add возвращает false если уже есть
  }).toList();
}

Производительность:

  • contains(): O(1) в среднем
  • add()/remove(): O(1) в среднем
  • Итерация: O(n)

Когда использовать Set вместо List:

  • Нужна гарантия уникальности элементов
  • Частые проверки наличия элемента
  • Операции с множествами (объединение, пересечение)
  • Удаление дубликатов из коллекции