Map это Iterable состоящее из пар ключ значение (также называемых связкой или ассоциативным массивом).
Scala Объект Predef предоставляет неявное преобразование, позволяющее записать пару (ключ, значение)
используя альтернативный синтаксис вида ключ -> значение
. Например, Map("x" -> 24, "y" -> 25, "z" -> 26)
означает тоже самое что и Map(("x", 24), ("y", 25), ("z", 26))
, но читается лучше.
Основные операции на мапах аналогичны темже операциям на множества. Рассмотрим в следующей таблице обобщеный и сгруппированный по категориям список методов на мапах:
- Запросы операции
apply
,get
,getOrElse
,contains
, иisDefinedAt
. Они превращают мапы в частично определенные функции от ключей к значениям. Основной “запросный метод” на мапах это :def get(key): Option[Value]
. Операция “m get key
” проверяет содержит ли мапа связанное значение для ключаkey
. Если да, то возвращает это связанное значение обернутое вSome
. Если же нет, тоget
возвращаетNone
. На мапах еще определен методapply
, которое напрямую возвращает связанное с заданным ключем значение, без оборачивания его вOption
. В этом случае, когда ключ не определен, будет брошено исключение. - Добавление и обновления
+
,++
,updated
, которые позволяют добавлять новые пары к мапам или изменять существующие. - Удаления
-
,--
, которые позволяют удалять пары из мап. - Создание подколлеций
keys
,keySet
,keysIterator
,values
,valuesIterator
, которые возвращают ключи и значения мап отдельно в различных формах. - Трансформации
filterKeys
иmapValues
, которые создают новую мапу через фильтрацию и преобразования элементов существующей мапы.
Операции на Классе Map
ПРИМЕР | ЧТО ДЕЛАЕТ |
---|---|
Запросы: | |
ms get k |
Возвращает значение связанное с ключом k в мапе ms обернутое в опшен, None если значение не найдено. |
ms(k) |
(либо эквивалент ms apply k ) Возвращает напрямую значение, связанное с ключом k на мапе ms , или исключение, если оно не найдено. |
ms getOrElse (k, d) |
Значение, связанное с ключом k на мапе ms , или значением по умолчанию d , если не найдено. |
ms contains k |
Проверяет, содержит ли ms значение для ключа k . |
ms isDefinedAt k |
Тоже самое что и contains . |
Подколлекции: | |
ms.keys |
Итерируемая коллекция, содержащая каждый ключ из мапы ms . |
ms.keySet |
Множество, содержащее каждый ключ из ms . |
ms.keysIterator |
Итератор, выдающий каждый ключ из ms . |
ms.values |
Итерируемая коллекция, содержащая каждое значение, связанное с ключом из ms . |
ms.valuesIterator |
Итератор, выдающий каждое значение, связанное с ключом из ms . |
Преобразования: | |
ms.view filterKeys p |
Отображение мапы, содержащее только те пары из ms , в которых ключ удовлетворяет предикату p . |
ms.view mapValues f |
Представление мапы ms к значениям которой применена функция f . |
Неизменяемые мапы поддерживают операции добавления и удаления элементов через возврат новых Мап
ов, как описано в следующей таблице.
Операции на Классе immutable.Map
ПРИМЕР | ЧТО ДЕЛАЕТ |
---|---|
Добавления и обновления: | |
ms.updated(k, v) или ms + (k -> v) |
Мапа, содержащая все пары из ms , а также ассоциативную связь k -> v от ключа k к значению v . |
Удаления: | |
ms remove k или ms - k |
Мапа, содержащая все пары ms за исключением пары с ключом k . |
ms removeAll ks или ms -- ks |
Мапа, содержащая все пары из ms за исключением пары с ключом из ks . |
Изменяемые мапы поддерживают дополнительные операции, которые представленным в таблице ниже.
Операции на Классе mutable.Map
ПРИМЕР | ЧТО ДЕЛАЕТ |
---|---|
Добавления и обновления: | |
ms(k) = v |
(либо эквивалент ms.update(x, v) ). Добавляет связь от ключа k к значению v в мапе ms через побочный эффект, перезаписывая любую предыдущую связь с k . |
ms.addOne(k -> v) либо ms += (k -> v) |
Добавляет связь от ключа k к значению v в мапе ms через побочный эффект и возвращает сам ms . |
ms addAll xvs либо ms ++= kvs |
Добавляет все пары из kvs к ms через побочный эффект и возвращает сам ms . |
ms.put(k, v) |
Добавляет связь от ключа k к значению v в мапе ms и возвращает любое значение, которое было ранее связанно с k (опционально). |
ms getOrElseUpdate (k, d) |
Если ключ k определен на мапе ms , возвращает связанное с ним значение. В противном случае добавляет к ms связь вида k -> d и возвращает d . |
Удаления: | |
ms subtractOne k либо ms -= k |
Удаляет ассоциированную связь с ключом k из мапы ms побочным эффектом и возвращает сам ms . |
ms subtractAll ks либо ms --= ks |
Удаляет все пары связанные с ключами ks из мапы ms побочным эффектом и возвращает сам ms . |
ms remove k |
Удаляет любую пару связанную с ключом k из ms и возвращает значение, которое ранее было связанное с k (опционально). |
ms filterInPlace p |
Оставляет только те пары в мапе ms , у которых ключ, удовлетворяет предикату p . |
ms.clear() |
Удаляет все пары из мапы ms |
Преобразования: | |
ms mapValuesInPlace f |
Преобразует все значения в мапе ms используя функцию f . |
Клонирования: | |
ms.clone |
Возвращает новую изменяемую мапу с теми же парами, что и у ms . |
Операции добавления и удаления в мапах совпадают с операциями добавления и удаления у множеств. Изменяемая мапа m
обычно обновляется через замену значений в самой себе, используя два варианта синтаксиса m(key) = value
или m += (key -> value)
. Существует также вариант m.put(key, value)
, который возвращает Option
, содержащее значение, ранее связанного с key
, или None
, если key
не было в мапе.
Функция getOrElseUpdate
полезна для доступа к мапам, работающим в качестве кэша. Допустим, у вас есть дорогая для вычисления операция, вызываемая функцией f
:
scala> def f(x: String) = {
println("taking my time."); sleep(100)
x.reverse }
f: (x: String)String
Допустим, что f
без побочных эффектов, поэтому повторное обращение к функции с тем же аргументом всегда будет давать один и тот же результат. В этом случае можно сэкономить время, сохранив ранее вычисленное выражение связав аргумент с результатом f
на мапе и вычислять f
только в том случае, если результат для аргумента не находится в мапе. Можно сказать, что мапа представляет собой кэш для вычислений функции f
.
scala> val cache = collection.mutable.Map[String, String]()
cache: scala.collection.mutable.Map[String,String] = Map()
Теперь вы можете создать более эффективную кэшированную версию функции f
:
scala> def cachedF(s: String) = cache.getOrElseUpdate(s, f(s))
cachedF: (s: String)String
scala> cachedF("abc")
taking my time.
res3: String = cba
scala> cachedF("abc")
res4: String = cba
Обратите внимание, что второй аргумент для getOrElseUpdate
вызывается “по имени”, поэтому вычисление f("abc")
производится только если getOrElseUpdate
запросит значения второго аргумента, точнее если его первый аргумент не найден в мапе cache
. Вы могли бы реализовать cachedF
самостоятельно, используя только базовые операции с мапами, но для этого понадобилось бы больше кода:
def cachedF(arg: String) = cache get arg match {
case Some(result) => result
case None =>
val result = f(x)
cache(arg) = result
result
}
Contributors to this page:
Contents
- Введение
- Изменяемые и Неизменяемые Коллекции
- Трейт Iterable
- Последовательности. Трейт Seq, IndexedSeq и LinearSeq
- Множества
- Мапы
- Реализации Неизменяемых Коллекций
- Реализации Изменяемых Коллекций
- Массивы
- Строки
- Показатели производительности
- Равенство
- Отображения
- Итераторы
- Создание коллекций с нуля
- Преобразования между Java и Scala коллекциями