该 文件 说 Set.head
返回“第一个”项,和 .tail
返回“除了第一个之外的所有”。*因为a Set
没有真正的“第一”项目,文档警告说,如果没有有序类型,您可能会在不同的运行中获得不同的结果。但你保证尾巴不包括头部吗?
我问的原因是我想知道是否可以降低一个 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
并且返回以便在每次递归时分离头部和尾部。
*实际上,它说“选择第一项”和“选择除第一项之外的所有项目”。我认为“选择”只是一个糟糕的选择。如果有理由说“选择”而不是“退货”,请告诉我。
依靠 head
和 tail
上 Set
(没有订购)充其量是冒险的。
在你的情况下,只需得到一个 Iterator
从你的 Set
先用 theSet.toIterator
,然后递归迭代器。当然,迭代器保证第一个元素与其他元素不同。
依靠 head
和 tail
上 Set
(没有订购)充其量是冒险的。
在你的情况下,只需得到一个 Iterator
从你的 Set
先用 theSet.toIterator
,然后递归迭代器。当然,迭代器保证第一个元素与其他元素不同。
我对这一点并不是100%肯定,因为我没有太多关注实现,但对于任何实现 HashSet
有一个隐含的顺序基于 hashCode
(类型 Int
)已经存在的值 Set
。
这意味着任何 Set
例如,打电话给 head
和 tail
会尊重这种排序,所以它不会是相同的元素。更重要的是,通过给定的元素连续迭代 Set
实例应该以相同的顺序生成元素,因为 Set
是不可改变的。
需要注意的是,虽然排序是未知的,但是对于任何实例都有一个,当你将一个新元素添加(可变或不可变)时,它可能会改变。 Set
。
你可以这样做:
val set = Set(1, 2, 3)
val head = set.head
val tail = set - head
这保证了它们相互排斥。