documentation表示Set.head
返回"第一个"项目,.tail
返回"除了第一个"。*因为Set
确实没有"第一个" item,文档警告说,如果没有有序类型,您可能会在不同的运行中获得不同的结果。但是你能保证尾巴不会包含头部吗?
我问的原因是我想知道是否可以像这样递减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
并返回更好,以便在每次递归时分开头尾。
答案 0 :(得分:4)
我对这一点并不是百分之百确定,因为我对实现并没有过多的看法,但对于任何HashSet
,都有基于{{hashCode
的隐式排序。 1}}(Int
类型)已在Set
中的值。
这意味着,对于任何Set
实例,对head
和tail
的调用都会尊重该排序,因此它不会是同一个元素。更重要的是,通过给定Set
实例的元素的连续迭代应该以相同的顺序产生元素,因为Set
是不可变的。
需要注意的是,虽然排序是未知的,但是对于任何实例都有一个,只要您将新元素添加(可变地或不可变地)到Set
,它就可能会发生变化。
答案 1 :(得分:4)
依赖head
和tail
Set
(无需订购)充其量是冒险的。
在您的情况下,只需先使用Iterator
从Set
获取theSet.toIterator
,然后递归迭代器。当然,迭代器保证第一个元素与其他元素不同。
答案 2 :(得分:3)
你可以这样做:
val set = Set(1, 2, 3)
val head = set.head
val tail = set - head
这可以保证它们互相排斥。