Ответ 1
Четыре реализованных вами списка относятся к трем группам:
-
"literal":
PersistentArrayMap
иPersistentHashMap
: основные типы карт, используемые при работе с символами карты (хотя функции конструктора также доступны с различным поведением по обработке дубликатов ключей - в Clojure 1.5.x литералы бросают исключения, когда обнаруживают повторяющиеся ключи, функции конструктора работают как повторяющиеся слева направоconj
ing, это поведение эволюционирует от версии к версии). Карты массивов получают распространение на хэш-карты при росте за пределами определенного количества записей (9 IIRC). Карты массивов существуют, потому что они быстрее для небольших карт; они также отличаются от хэш-карт тем, что они сохраняют записи в порядке ввода до продвижения на хэш-карту (вы можете использоватьclojure.core/array-map
для получения сколь угодно больших массивов карт, что может быть полезно, если вы действительно знаете, что вам выгодно использовать порядок вставки traversals и map не будут слишком большими, возможно, немного превышать обычный порог, NB. Последующаяassoc
к такой карте негабаритных массивов вернет хэш-карту). Массивные карты используют массивы с ключами и значениями чередуются; PHM использует постоянную версию массива хешей Phil Bagwell, сопоставленную с раздельной цепочкой для хэш-коллизий и отдельных типов node для преимущественно пустых и наименее полунаполненных узлов и легко представляет собой самую сложную структуру данных в Clojure. -
sorted:
PersistentTreeMap
экземпляры создаются только специальным запросом (вызовsorted-map
илиsorted-map-by
). Они реализованы как красно-черные деревья и сохраняют записи в определенном порядке, как указано компараторомcompare
по умолчанию, если он создан с помощьюsorted-map
или поставляемого пользователем компаратора, если он создан с помощьюsorted-map-by
. -
специальный, возможно, устаревший:
PersistentStructMap
не используется очень часто и в основном рассматривается как устаревший в пользу записей, хотя я фактически не могу вспомнить прямо сейчас, если когда-либо было официальное уведомление об отказе. Первоначальная цель заключалась в том, чтобы обеспечить карты с особенно быстрым доступом к некоторым часто используемым клавишам. Теперь это можно сделать с помощью записей при использовании ключевых слов для доступа к полю (с ключевым словом в позиции оператора:(:foo instance-of-some-record-with-field-foo)
), хотя важно отметить, что записи не являются=
регулярными картами с одинаковыми записями.
Все эти четыре встроенных типа карты попадают в один и тот же "раздел равенства", то есть любые две карты одного из четырех классов, упомянутых выше, будут равны, если (и только если) они содержат одни и те же ключи (как определяется Clojure =
) с теми же соответствующими значениями. Записи, как упоминалось выше в 3, являются похожими на карты, но каждый тип записи формирует свой собственный раздел равенства.