Коллекции придерживаются единого подхода к определению равенства и получению хэшей. Идея состоит, во-первых, в том, чтобы разделить коллекции на группы: множества, мапы и последовательности. Коллекции в разных группах всегда различаются. Например, Set(1,2,3)
неравнозначен списку List(1,2,3)
, хотя они содержат одни и те же элементы. С другой стороны, в рамках одной и той же группы коллекции равны тогда и только тогда, когда они имеют одинаковые элементы (для последовательностей: одни и те же элементы в одном порядке). Например List(1, 2, 3) == Vector(1, 2, 3)
, и HashSet(1, 2) == TreeSet(2, 1)
.
Для проверки на равенство не важно, является ли коллекция изменяемой или неизменяемой. Для изменяемой коллекции достаточно просто рассмотреть ее текущие элементы на момент проведения проверки на равенство. Это означает, что коллекция в разные моменты может быть эквивалентна разным коллекциям, в зависимости от того, какие элементы в неё добавляются или удаляются. В этом кроится потенциальная опасность при использовании изменяемой коллекции в качестве ключа для хэшмапы. Пример:
scala> import collection.mutable.{HashMap, ArrayBuffer}
import collection.mutable.{HashMap, ArrayBuffer}
scala> val buf = ArrayBuffer(1, 2, 3)
buf: scala.collection.mutable.ArrayBuffer[Int] =
ArrayBuffer(1, 2, 3)
scala> val map = HashMap(buf -> 3)
map: scala.collection.mutable.HashMap[scala.collection.
mutable.ArrayBuffer[Int],Int] = Map((ArrayBuffer(1, 2, 3),3))
scala> map(buf)
res13: Int = 3
scala> buf(0) += 1
scala> map(buf)
java.util.NoSuchElementException: key not found:
ArrayBuffer(2, 2, 3)
В этом примере запрос в последней строке, скорее всего, не сработает, так как хэш-код массива buf
изменился во второй с конца строке. Таким образом, в поиске элемента на основе хэша, будет запрашиваться совсем другой элемент, чем тот что был первоначально сохранен в map
.
Contributors to this page:
Contents
- Введение
- Изменяемые и Неизменяемые Коллекции
- Трейт Iterable
- Последовательности. Трейт Seq, IndexedSeq и LinearSeq
- Множества
- Мапы
- Реализации Неизменяемых Коллекций
- Реализации Изменяемых Коллекций
- Массивы
- Строки
- Показатели производительности
- Равенство
- Отображения
- Итераторы
- Создание коллекций с нуля
- Преобразования между Java и Scala коллекциями