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

时间:2016-04-02 18:26:43

标签: 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)

有更好的方法吗?

2 个答案:

答案 0 :(得分:5)

Scala的Set层次结构有点奇怪,但BitSetSet[Int]作为超类型,因此您只需将BitSet传递给需要Set[Int]等的方法

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

如果您有幸使用immutableSetBitSet版本,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

如果您有scala.collection.BitSet,请使用toSet

scala> takesSet(scala.collection.BitSet(0, 100, 200).toSet)
res1: Int = 3

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

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)

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

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

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

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

但是BitSet参数不是在collection.breakOut之前构造一个中间集(和序列),而是告诉编译器使用CanBuildFrom类型类的实例来执行映射。直接构造BitSet。以这种方式明确传递CanBuildFrom实例不仅适用于map,它也适用于flatMapscanLeft++和其他允许您更改元素类型的集合操作。

答案 1 :(得分:0)

思考面向对象:BitSet 一个Set[Int],你不需要做任何事情来将一个转换为另一个:

     import scala.collection._
     val set: Set[Int] = BitSet(1,2,3)

走另一条路更难,并且需要线性时间:

     val bs: BitSet = BitSet(set.toStream:_*)

但是每当你发现自己需要这种" upconverting"时,99%的时间都是设计糟糕的标志,应该改进以消除需求:特定的实现细节{ {1}}应该只对最初创建它的代码有用,下游代码通常应该与实现无关。