Являются ли голова и хвост набора гарантией взаимоисключающим?
Документация говорит, что Set.head
возвращает "первый" элемент, а .tail
возвращает "все, кроме первого". * Поскольку a Set
doesn На самом деле у него есть "первый" элемент, документация предупреждает, что без упорядоченного типа вы можете получить другой результат на разных прогонах. Но гарантированы ли вы, что хвост не будет включать голову?
Причина, по которой я спрашиваю, - мне интересно, нормально ли это записать Set
следующим образом:
def recurse(itemsToExamine: Set[Item], acc: Result): Result =
if (itemsToExamine.isEmpty) acc
else {
val item = itemsToExamine.head
recurse(
item.spawnMoreItems ++ itemsToExamine.tail,
acc.updatedFor(item))
}
Если это законно, это, безусловно, будет лучше, чем преобразование с Set
в Seq
и обратно, чтобы разделить голову и хвост на каждой рекурсии.
* Фактически, он говорит "выбирает первый элемент" и "выбирает все, кроме первого элемента". Я предполагаю, что "выбор" - это просто плохой выбор слова. Если есть причина говорить "выбирает", а не "возвращает", пожалуйста, дайте мне знать.
Ответы
Ответ 1
Я не уверен на 100%, потому что я не слишком много смотрел на реализацию, но для любого HashSet
существует неявное упорядочение на основе hashCode
(типа Int
) значения, которые уже находятся в Set
.
Это означает, что для любого экземпляра Set
вызовы head
и tail
будут относиться к этому упорядочению, поэтому он не будет тем же самым элементом. Более того, последовательная итерация через элементы данного экземпляра Set
должна приводить элементы в том же порядке, потому что Set
является неизменным.
Вывод заключается в том, что, пока порядок неизвестен, для любого экземпляра есть один, который может измениться, как только вы добавите (изменчиво или неизменно) новый элемент в Set
.
Ответ 2
Опора на head
и tail
на Set
(без упорядочивания) в лучшем случае является рискованной.
В вашем случае просто выберите Iterator
из своего Set
сначала с помощью theSet.toIterator
, а затем перезапустите итератор. Итератор гарантирует, что первый элемент будет отличаться от остальных, конечно.
Ответ 3
Вы можете сделать это:
val set = Set(1, 2, 3)
val head = set.head
val tail = set - head
Это гарантирует, что они будут взаимоисключающими.