在Scala中将BitSet设置为[Int]或反之亦然

pro*_*eek 4 scala set bitset

我有一个使用BitSet的库,我需要更改Set [Int]类型数据才能使用该库.

我想到的是使用.toSeq:_*操作,但我不确定这是从BitSet转换为Set [Int]还是反过来的有效方法.

scala> BitSet(Set(1,2,3).toSeq:_*)
res55: scala.collection.immutable.BitSet = BitSet(1, 2, 3)

scala> Set(BitSet(1,2,3).toSeq:_*)
res56: scala.collection.immutable.Set[Int] = Set(1, 2, 3)
Run Code Online (Sandbox Code Playgroud)

有没有更好的办法?

Tra*_*own 5

Scala的Set层次结构是有点怪异,但它是那么回事BitSetSet[Int]作为超类型,所以你可以简单地传递一个BitSet到需要一个方法Set[Int],等等.

这似乎不是这种情况,因为Set默认情况下你得到的是immutable.Set(下scala.collection),而你正在使用的库可能是BitSet直接使用的scala.collection,而不是immutable.BitSet.在您的示例代码中并非如此,其中包含所有内容immutable,但我不确定它是多么简化.

如果你足够幸运与合作immutable两个包的版本SetBitSet中,BitSetSet方向很简单:

scala> import scala.collection.immutable.BitSet
import scala.collection.immutable.BitSet

scala> val bs = BitSet(0, 100, 200)
bs: scala.collection.immutable.BitSet = BitSet(0, 100, 200)

scala> def takesSet(s: Set[Int]): Int = s.size
takesSet: (s: Set[Int])Int

scala> takesSet(bs)
res0: Int = 3
Run Code Online (Sandbox Code Playgroud)

如果你有一个scala.collection.BitSet,只需使用toSet:

scala> takesSet(scala.collection.BitSet(0, 100, 200).toSet)
res1: Int = 3
Run Code Online (Sandbox Code Playgroud)

对于另一个方向,你的版本很好:

scala> val s = Set(1, 2, 3)
s: scala.collection.immutable.Set[Int] = Set(1, 2, 3)

scala> BitSet(s.toSeq: _*)
res2: scala.collection.immutable.BitSet = BitSet(1, 2, 3)
Run Code Online (Sandbox Code Playgroud)

但值得注意的是,在许多情况下,你可以通过一些CanBuildFrom魔法避免这种转换:

scala> val bs: BitSet = Set("1", "2", "3").map(_.toInt)(collection.breakOut)
bs: scala.collection.immutable.BitSet = BitSet(1, 2, 3)
Run Code Online (Sandbox Code Playgroud)

这会产生与以下相同的结果:

scala> val bs: BitSet = BitSet(Set("1", "2", "3").map(_.toInt).toSeq: _*)
bs: scala.collection.immutable.BitSet = BitSet(1, 2, 3)
Run Code Online (Sandbox Code Playgroud)

但是,而不是构建前的中间组(和序列)BitSet中,collection.breakOut参数告诉编译器使用的一个实例来执行地图CanBuildFrom类型的类,将构建BitSet直接.传递一个CanBuildFrom以这种方式明确实例不仅仅是为map,与非彼稍后即工作flatMap,scanLeft,++,和其他收藏品操作,它允许您更改元素类型.