Ответ
Swift использует метод цепочек (separate chaining) для разрешения коллизий в Dictionary.
Механизм работы:
- Каждая "корзина" (bucket) в хеш-таблице содержит связанный список (или массив) элементов.
- При добавлении элемента с ключом, чей хеш совпадает с хешем существующего ключа в той же корзине, новый элемент добавляется в этот список.
- При поиске по ключу система:
- Вычисляет хеш ключа.
- Находит соответствующую корзину.
- Последовательно проверяет (через сравнение
==) все ключи в списке этой корзины, чтобы найти точное совпадение.
Пример и последствия:
var dictionary = [Int: String]()
// Предположим, что ключи 1 и 101 дают одинаковый хеш и попадают в одну корзину.
dictionary[1] = "One"
dictionary[101] = "One Hundred One" // Коллизия: элемент добавляется в список внутри корзины.
let value = dictionary[101] // Поиск: вычисляется хеш 101, находится корзина, в её списке находится ключ 101.
Важно:
- В худшем случае (все ключи в одной корзине) сложность операций падает с O(1) до O(n).
- Swift автоматически выполняет ресайзинг (rehashing) таблицы при высокой нагрузке (большом коэффициенте заполнения), чтобы уменьшить количество коллизий и сохранить производительность.
- Качество встроенной хеш-функции (
hash(into:)) минимизирует коллизии на практике.