我正在Scala的Play Framework中的後端服務器上工作。但是,我調用返回Java列表(util.List)的外部庫(用java編寫)。我爲列表中包含的對象創建了寫入,但是我不知道如何爲實際列表寫入寫入,以便它可以是通用的(無需爲列表和列表寫入「寫入」只是A和B的寫入)。JSON寫入Java列表
我知道我可以使用JavaConversions將Java列表轉換爲Scala Seq(已經實現了Writes),但由於速度是必不可少的,我不想做額外的轉換。
我正在Scala的Play Framework中的後端服務器上工作。但是,我調用返回Java列表(util.List)的外部庫(用java編寫)。我爲列表中包含的對象創建了寫入,但是我不知道如何爲實際列表寫入寫入,以便它可以是通用的(無需爲列表和列表寫入「寫入」只是A和B的寫入)。JSON寫入Java列表
我知道我可以使用JavaConversions將Java列表轉換爲Scala Seq(已經實現了Writes),但由於速度是必不可少的,我不想做額外的轉換。
這裏是一個可能的實現
import play.api.libs.json.{JsArray, JsValue, Json, Writes}
import scala.collection.JavaConverters._
implicit def jListWrites[A: Writes] = new Writes[java.util.List[A]] {
override def writes(o: util.List[A]): JsValue = {
JsArray(o.asScala.map(Json.toJson(_)))
}
}
不創建一個單一的Writes
而是一種方法,可以創建它們用於定義了Writes
的任何類型。
你說你想避免JavaConversions
,但你可以看到它是困難的,因爲JsArray
需要一個Seq[JsValue]
無論如何,所以你需要構建一個階Seq
這種或那種方式。
我這裏顯示什麼是或多或少等同於使用asScala
轉換的java List
Scala的mutable.Buffer
並使用默認Writes
的Traversable
。
請注意,轉換可能不像您想象的那樣廣泛,它們只是創建包裝,不涉及複製。
這是我能在性能
implicit def jListWrites[A: Writes] = new Writes[java.util.List[A]] {
override def writes(o: util.List[A]): JsValue = {
val buffer = new Array[JsValue](o.size)
var i = 0
while (i < o.size) {
buffer(i) = Json.toJson(o.get(i))
i += 1
}
JsArray(buffer)
}
}
它需要達到1000000和Int
第29毫秒相比,39毫秒的簡單的實現條件來最好的。請注意,Int
很容易轉換,如果您的對象更復雜,加速將會更小。
轉換20000那些case class C(num: Int, n2: Int, s: String)
給出了相同的結果(直接更快0.14毫秒)。
您可以編寫一個Writes
是重用現有的斯卡拉List
import java.util.{ List => JList }
implicit def JListWrites[T](implicit sw: Writes[List[T]]): Writes[JList[T]]) = Write[JList[T]] { jlist =>
sw.writes(jlist.asScala)
}
謝謝。這正是我所期待的。 –