Ответ
В Dart (и, соответственно, в Flutter) ключом в HashMap (или в Map, который часто реализуется через хэш-таблицу) может быть любой объект, для которого корректно определены методы operator == (оператор равенства) и геттер hashCode.
Ключевое правило: Если два объекта считаются равными по ==, они обязаны иметь одинаковый hashCode. Обратное не обязательно: разные объекты могут иметь одинаковый хэш (коллизия), но это снижает производительность.
Примеры допустимых ключей в Dart:
-
Встроенные типы с корректной реализацией:
int,double,String,bool,DateTime,Uri.final Map<String, int> phoneBook = {'Alice': 12345, 'Bob': 67890}; final Map<DateTime, String> events = {DateTime(2024, 1, 1): 'New Year'}; -
Экземпляры пользовательских классов, где
==иhashCodeпереопределены. Класс должен быть immutable (все поляfinal), чтобы его хэш-код не менялся после помещения в карту.class ProductKey { final String id; final String category; ProductKey(this.id, this.category); @override bool operator ==(Object other) => identical(this, other) || other is ProductKey && runtimeType == other.runtimeType && id == other.id && category == other.category; @override int get hashCode => Object.hash(id, category); // Используем Object.hash } void main() { final inventory = HashMap<ProductKey, int>(); final key = ProductKey('prod_1', 'electronics'); inventory[key] = 100; print(inventory[ProductKey('prod_1', 'electronics')]); // 100 }
Что НЕЛЬЗЯ использовать в качестве ключа (без переопределения методов):
List,Set,Mapи другие коллекции по умолчанию. Их равенство сравнивает идентичность ссылок, а не содержимое.- Мутабельные (изменяемые) объекты. Если изменить поле объекта после того, как он использовался как ключ, его
hashCodeизменится, и найти значение по этому ключу станет невозможно. - Пользовательские классы без переопределения
==иhashCode. Для них будет использоваться сравнение по ссылке (identical), что редко является нужным поведением.
Для автоматической генерации == и hashCode в Dart можно использовать пакет equatable или аннотации вроде @immutable и кодогенерацию.