Ответ
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:
-
HashSet (по умолчанию):
final hashSet = HashSet<int>(); // Быстрый доступ, порядок не сохраняется -
LinkedHashSet (сохраняет порядок вставки):
final orderedSet = LinkedHashSet<String>(); orderedSet.addAll(['z', 'a', 'b']); print(orderedSet); // {z, a, b} - порядок сохранен -
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:
- Нужна гарантия уникальности элементов
- Частые проверки наличия элемента
- Операции с множествами (объединение, пересечение)
- Удаление дубликатов из коллекции
Ответ 18+ 🔞
А, Set в Dart, ну это ж просто ёперный театр с уникальностью! Представь себе такую картину: у тесть есть мешок с яблоками, и ты туда пытаешься запихнуть ещё одно такое же яблоко. Set смотрит на тебя, как на идиота, и говорит: «Чувак, ты веришь, что я этого не замечу?» И просто игнорирует твои потуги. В отличие от List, который, как распиздяй, возьмёт всё что дают, хоть десять одинаковых яблок — ему да похуй.
Основная фишка у него вот какая:
- Все элементы там уникальные — дубликаты он выкидывает нахуй сразу.
- Порядок, как правило, не гарантирует (ну кроме одного особого случая, о нём ниже).
- Но зато найти элемент (
contains) или добавить/удалить — это ебушки-воробушки, в среднем моментально (O(1)), не то что в списке, где надо всё перебирать.
Создаётся это чудо просто:
// Прям так, литералом
Set<String> фрукты = {'яблоко', 'банан', 'апельсин'};
// Или через конструктор
Set<int> цифры = Set();
цифры.addAll([1, 2, 3, 3, 2, 1]); // И что получится? Правильно, {1, 2, 3}. Всё лишнее — нахуй!
// Из любой другой коллекции, чтоб дубли убрать
Set<String> уникальныеИмена = Set.from(['Анна', 'Боря', 'Анна']);
print(уникальныеИмена); // {Анна, Боря} — второй Анне **доверия ебать ноль**.
А вот тут, бля, внимание, потому что Set'ов есть аж три вида, и они разные, как хуй в пальто и манда с ушами:
-
HashSet (он же по умолчанию):
final hashSet = HashSet<int>(); // Быстрый, шустрый, но порядок элементов может быть какой угодно. Полный **хитрая жопа**. -
LinkedHashSet (вот этот — красавчик, если порядок важен):
final orderedSet = LinkedHashSet<String>(); orderedSet.addAll(['z', 'a', 'b']); print(orderedSet); // {z, a, b} — запомнил, в каком порядке ты их впихнул. Уважительный. -
SplayTreeSet (ну это уже полупидор-перфекционист, всё по полочкам):
final sortedSet = SplayTreeSet<int>((a, b) => b.compareTo(a)); sortedSet.addAll([3, 1, 4, 1, 5]); print(sortedSet); // {5, 4, 3, 1} — сам всё отсортировал по убыванию, как я сказал. **Удивление пиздец**.
Самые соковые операции, где Set реально пизда рулю:
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> выбранныеАйдишники = {};
void тумблерВыбора(String id) {
if (выбранныеАйдишники.contains(id)) {
выбранныеАйдишники.remove(id); // Развыбрал
} else {
выбранныеАйдишники.add(id); // Выбрал
}
setState(() {}); // Перерисуйся, сука
}
// Или вот — убрать дубликаты из списка, чтоб не позориться
List<Product> убратьПовторы(List<Product> товары) {
final уникальныеАйди = Set<String>();
return товары.where((товар) {
return уникальныеАйди.add(товар.id); // Метод add возвращает false, если такой id УЖЕ есть в сете. Гениально и просто.
}).toList();
}
По скорости (чтоб не бздеть попусту):
contains(),add(),remove()— в среднем O(1), то есть почти мгновенно.- Пройтись по всем элементам — O(n), как и везде.
Итог: когда брать Set?
- Когда нужно, чтобы всё было уникальное, а дубли — на хуй.
- Когда постоянно надо проверять, есть ли элемент в коллекции.
- Когда нужно делать операции объединения, пересечения — тут ему нет равных.
- Когда из большого овердохуища данных нужно выковырять только уникальные значения.
Короче, хуй с горы — инструмент офигенный, главное, понять, когда его использовать, а не тыкать везде, где попало.
Видео-ответы
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶
▶