← Назад к вопросам
С помощью каких методов добивается уникальность элементов в set?
1.7 Middle🔥 151 комментариев
#Архитектура Flutter#ООП и паттерны
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI26 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Методы достижения уникальности элементов в Set
В Dart Set обеспечивает уникальность элементов через механизм хеширования и равенства (equality). Это один из ключевых аспектов работы с коллекциями в Dart.
Основной механизм: hashCode и equals
Для любого объекта в Dart существуют два критических метода:
class User {
final int id;
final String name;
User(this.id, this.name);
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is User &&
runtimeType == other.runtimeType &&
id == other.id &&
name == other.name;
@override
int get hashCode => id.hashCode ^ name.hashCode;
}
Как это работает:
- hashCode — возвращает целое число, которое служит "первичным ключом" для быстрого поиска
- operator == — проверяет точное равенство двух объектов
- Set сначала проверяет hashCode, затем если хеши совпадают, проверяет ==
Практический пример
final users = <User>{};
final user1 = User(1, Alice);
final user2 = User(1, Alice);
final user3 = User(2, Bob);
users.add(user1);
users.add(user2); // Не добавится, так как user1 == user2
users.add(user3); // Добавится
print(users.length); // 2
Встроенные типы
Для примитивных типов (int, String, bool) hashCode и operator == уже реализованы:
final numbers = {1, 2, 3, 2, 1};
print(numbers); // {1, 2, 3}
final strings = {flutter, dart, flutter};
print(strings.length); // 2
Проблемы и gotchas
❌ Неправильно:
class Product {
final int id;
Product(this.id);
// Нет переопределения hashCode и operator ==
}
final p1 = Product(1);
final p2 = Product(1);
final set = {p1, p2};
print(set.length); // 2! Хотя логически они одинаковые
✅ Правильно:
class Product {
final int id;
Product(this.id);
@override
bool operator ==(Object other) =>
other is Product && id == other.id;
@override
int get hashCode => id.hashCode;
}
final p1 = Product(1);
final p2 = Product(1);
final set = {p1, p2};
print(set.length); // 1
Оптимизация хеширования
Для сложных объектов используй Quiver или Equatable:
import package:equatable/equatable.dart;
class Order extends Equatable {
final int id;
final String customerName;
final List<String> items;
Order(this.id, this.customerName, this.items);
@override
List<Object?> get props => [id, customerName, items];
}
// Теперь hashCode и operator == генерируются автоматически
final order1 = Order(1, Alice, [item1]);
final order2 = Order(1, Alice, [item1]);
final orders = {order1, order2};
print(orders.length); // 1
LinkedHashSet для сохранения порядка
Обычный Set не гарантирует порядок элементов. Используй LinkedHashSet:
final set = LinkedHashSet<int>();
set.addAll([3, 1, 2, 1, 3]);
print(set); // {3, 1, 2}
Заключение
Уникальность в Set достигается через комбинацию:
- hashCode для быстрого поиска коллизий
- operator == для точной проверки равенства
- Правильная реализация обоих методов в пользовательских классах
Всегда помни: если переопределяешь ==, то обязательно переопредели hashCode!