我有一个使用BitSet的库,我需要更改Set [Int]类型数据才能使用该库.
我想到的是使用.toSeq:_ *操作,但我不确定这是从BitSet转换为Set [Int]还是反过来的有效方法.
scala> BitSet(Set(1,2,3).toSeq:_*) res55: scala.collection.immutable.BitSet = BitSet(1,3) scala> Set(BitSet(1,3).toSeq:_*) res56: scala.collection.immutable.Set[Int] = Set(1,3)
有没有更好的办法?
解决方法
Scala的Set层次结构有点奇怪,但是BitSet将Set [Int]作为超类型,因此您可以简单地将BitSet传递给期望Set [Int]等的方法.
这似乎不是这种情况,因为默认情况下,您获取的Set是immutable.Set(在scala.collection下),而您正在使用的库可能是直接在scala.collection下使用BitSet,而不是不可变的.位集合.在您的示例代码中并非如此,其中所有内容都是不可变的,但我不确定它是多么简化.
如果你很幸运能够使用Set和BitSet的不可变包的版本,BitSet to Set方向是微不足道的:
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,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,200).toSet) res1: Int = 3
对于另一个方向,你的版本很好:
scala> val s = Set(1,3) s: scala.collection.immutable.Set[Int] = Set(1,3) scala> BitSet(s.toSeq: _*) res2: scala.collection.immutable.BitSet = BitSet(1,3)
但值得注意的是,在许多情况下,您可以通过一些CanBuildFrom魔术来避免这种转换:
scala> val bs: BitSet = Set("1","2","3").map(_.toInt)(collection.breakOut) bs: scala.collection.immutable.BitSet = BitSet(1,3)
这会产生与以下相同的结果:
scala> val bs: BitSet = BitSet(Set("1","3").map(_.toInt).toSeq: _*) bs: scala.collection.immutable.BitSet = BitSet(1,3)
但是,而不是在BitSet之前构造中间集(和序列),collection.breakOut参数告诉编译器使用将直接构造BitSet的CanBuildFrom类型类的实例来执行映射.以这种方式显式传递CanBuildFrom实例不仅适用于map,它也适用于flatMap,scanLeft和其他允许您更改元素类型的集合操作.