套装的头部和尾部是否保证相互排斥?

时间:2014-06-27 19:19:33

标签: scala recursion scala-collections

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并返回更好,以便在每次递归时分开头尾。

<小时/> *实际上,它说&#34;选择第一项&#34;和&#34;选择除第一项以外的所有项目#34;。我假设&#34;选择&#34;只是一个糟糕的选择。如果有理由说&#34;选择&#34;而不是&#34;返回&#34;,请告诉我。

3 个答案:

答案 0 :(得分:4)

我对这一点并不是百分之百确定,因为我对实现并没有过多的看法,但对于任何HashSet,都有基于{{hashCode的隐式排序。 1}}(Int类型)已在Set中的值。

这意味着,对于任何Set实例,对headtail的调用都会尊重该排序,因此它不会是同一个元素。更重要的是,通过给定Set实例的元素的连续迭代应该以相同的顺序产生元素,因为Set是不可变的。

需要注意的是,虽然排序是未知的,但是对于任何实例都有一个,只要您将新元素添加(可变地或不可变地)到Set,它就可能会发生变化。

答案 1 :(得分:4)

依赖headtail Set(无需订购)充其量是冒险的。

在您的情况下,只需先使用IteratorSet获取theSet.toIterator,然后递归迭代器。当然,迭代器保证第一个元素与其他元素不同。

答案 2 :(得分:3)

你可以这样做:

val set = Set(1, 2, 3)
val head = set.head
val tail = set - head

这可以保证它们互相排斥。