2016-04-02 56 views
4

我有一个使用BitSet的库,我需要将Set [Int]类型的数据更改为使用该库。BitSet设置[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) 

有没有更好的方法?

+0

第二,'.toSet'或'.seq'应该可以工作 – Bergi

+0

也许[初始化一个范围内的scala BitSet](http://stackoverflow.com/q/6366976/1048572)对第一个 – Bergi

回答

5

Scala的Set层次是有点怪异,但它是BitSet具有Set[Int]作为超类型的情况下,所以你可以简单地传递一个BitSet给需要一个Set[Int],方法等

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

如果你足够幸运,既SetBitSetimmutable包的版本中,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,它可以与flatMap,scanLeft,++以及其他允许您更改元素类型的集合操作一起使用。

0

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

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

走另一条路更难,并会采取线性时间:

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

但每当你发现自己需要这种“向上转换”的,时间的99%,它是坏的设计的标志,比应加以改进,以消除需要:实施细则Ø f特定的Set应该只与最初创建它的代码有关,下游代码通常应该与实现无关。

+0

我认为“99%”是非常乐观的。通常情况下,您需要使用'BitSet'(无论是因为第三方API还是因为您需要'BitSet'特定的操作),并且通常情况下您需要将“普通”设置为“BitSet”子类型以使其成为可能。 –

+1

@TravisBrown也许,我是一个乐观主义者:)我只是觉得很难想到一个用例,我需要一些设置,我没有创建_。我相信有一些,只是说我认为他们几乎不像人们在不考虑他们是否真的需要这些转换时那样来回转换。事实上,你从'Predef'得到的'Set'是'scala.collection.immutable.Set',而不是'scala.collection.Set'也不能帮助恕我直言。 – Dima