2014-05-23 85 views
5

我想以有效的方式將Java doubles(java.util.List [java.lang.Double])的Java列表轉換爲Scala雙精度(List [Double])的Scala列表。如何將java.util.List [java.lang.Double]轉換爲Scala的List [Double]?

目前我正在將每個Double值轉換爲Scala Double列表。我不想映射每個值,並且希望找到一個更有效的方法來做到這一點。

import collection.JavaConversions._ 
import collection.mutable.Buffer 

val j: java.util.List[java.lang.Double] = Buffer(new java.lang.Double(1.0), new java.lang.Double(2.0)) 
val s: List[Double] = ... 

我見過從Scala - > Java的文檔,但沒有太多其他的方法。

+0

「我看過從Scala - > Java的文檔,但沒有太多其他的方式。」......你現在做了什麼?小心分享這些信息? ;-) – Make42

+0

我發現了答案:https://stackoverflow.com/q/46830217/4533188 – Make42

回答

14

的建議是使用JavaConverters,不JavaConversions

import collection.JavaConverters._ 
import scala.collection.breakOut 
val l: List[Double] = j.asScala.map(_.doubleValue)(breakOut) 

doubleValue將其轉換從java.lang.Doublescala.DoublebreakOut告訴它產生一個List作爲map的結果,而不必再次遍歷它以轉換爲List。如果你不關心多餘的遍歷,你也可以只做toList而不是breakOut

Java類與Scala完全不同的對象;這不僅僅是一個名稱改變。因此,沒有遍歷就不可能進行轉換。您必須創建一個全新的集合,然後查看每個元素才能(轉換它)並將其移過。

類型不同的原因是java.lang.Double是一個「盒裝原語」,而scala.Double等同於Java的double原語。這裏的轉換本質上是「拆箱」原語。

+0

有沒有辦法做到這一點沒有任何遍歷?也許這不可能,但我天真地認爲演員不會涉及任何遍歷。 –

+0

請注意,如果您準確接受'Seq'而不是'List',則可以在調用'map之前通過調用'view'方法將Scala轉換的Java'List'轉換爲視圖來避免遍歷'。這會給你一個懶惰評估的'SeqView',它將根據需要將轉換應用到元素上。 – reggert

0
import collection.JavaConverters._ 

val javaList : java.util.List[Double] = ... 
val scalaList : List[Double] = j.asScala.toList 
+0

這是能夠投給一個java.util.list [雙]列表[雙],但棘手的部分是也從java.lang.Double轉換爲Scala Double。 –

+1

@Erik,這不是演員:'asScala'遍歷基於java的集合並構建一個全新的基於scala的集合。因爲課程完全不同。 – dhg

+0

@dhg,你其實是錯的。 'asScala'不會穿過集合; 'asScala'在原始集合中創建* view *。它是執行實際遍歷的'toList'。請參閱'scala.collection.convert.Wrappers'特徵:它包含這些視圖的實現,顯然它們只將集合操作轉發給原始Java集合。 –

相關問題