JSON 写入 Java 列表
Posted
技术标签:
【中文标题】JSON 写入 Java 列表【英文标题】:JSON Writes for Java List 【发布时间】:2016-06-21 07:35:43 【问题描述】:我正在使用 Scala 的 Play Framework 开发后端服务器。但是,我正在调用一个返回 Java 列表 (util.List) 的外部库(用 java 编写)。我为列表中包含的对象创建了一个写入,但是我不知道如何为实际列表编写写入,以便它可以是通用的(无需为列表和列表编写“写入”,只是 A 和 B 的写入)。
我知道我可以使用 JavaConversions 将 Java 列表转换为 Scala Seq(已经实现了 Writes),但由于速度至关重要,我不想进行额外的转换。
【问题讨论】:
【参考方案1】:这是一个可能的实现
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]
,所以你需要以一种或另一种方式构造一个scalaSeq
。
我在这里展示的内容或多或少等同于使用 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
s 需要 29 毫秒,而直接实现需要 39 毫秒。请注意,Int
很容易转换,如果您的对象更复杂,则加速会更小。
转换其中的 20000 个 case class C(num: Int, n2: Int, s: String)
会得到相同的结果(直接速度甚至快 0.14 毫秒)。
【讨论】:
谢谢。这正是我想要的。【参考方案2】:您可以编写一个 Writes
来重用现有的 Scala 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)
【讨论】:
以上是关于JSON 写入 Java 列表的主要内容,如果未能解决你的问题,请参考以下文章