2017-07-18 102 views
1

我正在處理混合的Java-Scala項目,並且經常需要轉換集合。包含基元的Scala集合的安全投射

當我要轉換的原語的集合,我應該寫這樣的事情

val coll: Seq[Int] = Seq(1, 2, 3) 

import scala.collection.JavaConverters._ 

val jColl = coll.map(v => Int.box(v)).asJava 

但是,我知道,與Java和Scala的泛型集合使用盒裝的價值觀,所以我可以有把握地避免迭代與不必要的拳擊和只寫

val jColl = coll.asJava.asInstanceOf[java.util.List[java.lang.Integer]] 

然而,編譯器不會抱怨,如果我不會在任何集合類型或元素的類型錯誤。

是否存在避免額外迭代的類型安全方法?是否至少有一種方法來保持收集類型的檢查?

+0

爲什麼'.asScala'? – cchantep

+1

類似的問題https://stackoverflow.com/questions/24620574/implicit-conversion-between-scala-long-and-java-lang-long-in-collections –

回答

1

嗯,我想不出一種方法來避免scala.Int - >java.lang.Integer轉換有點手動或不安全,但如果您只實現一次並重用它,它幾乎可以消除風險。

一種方法可能是:

import scala.language.higherKinds 
implicit class IntCollectionBoxer[C[_] <: java.lang.Iterable[_]](elems: C[Int]) { 
    def asJavaBoxed: C[java.lang.Integer] = elems.asInstanceOf[C[java.lang.Integer]] 
} 

(重複雙和其他類型)

然後使用會是這樣,這是非常難犯了一個錯誤搭配:

val jColl = coll.asJava.asJavaBoxed 

根據您的使用情況,您可能也希望更改C的界限。

+0

我認爲這是隱式def而不是隱式類的好地方。無論如何,只要更好的主意不會出現,接受答案。 –