Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala 为Java列表编写JSON_Scala_Playframework_Playframework 2.4 - Fatal编程技术网

Scala 为Java列表编写JSON

Scala 为Java列表编写JSON,scala,playframework,playframework-2.4,Scala,Playframework,Playframework 2.4,我正在Scala的Play框架中使用后端服务器。但是,我调用了一个外部库(用java编写),它返回一个java列表(util.list)。我为列表中包含的对象创建了一个写操作,但是我不知道如何为实际列表编写写操作,以便它可以是通用的(不需要为列表和列表编写“写操作”,只需为a和B编写) 我知道我可以使用JavaConversions将Java列表转换为Scala-Seq(已经实现了写操作),但由于速度至关重要,我不想做额外的转换。您可以编写一个写操作,将现有的一个重复用于Scala列表 impo

我正在Scala的Play框架中使用后端服务器。但是,我调用了一个外部库(用java编写),它返回一个java列表(util.list)。我为列表中包含的对象创建了一个写操作,但是我不知道如何为实际列表编写写操作,以便它可以是通用的(不需要为列表和列表编写“写操作”,只需为a和B编写)


我知道我可以使用JavaConversions将Java列表转换为Scala-Seq(已经实现了写操作),但由于速度至关重要,我不想做额外的转换。

您可以编写一个
写操作
,将现有的一个重复用于Scala
列表

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) 
}

下面是一个可能的实现

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(_)))
  }
}
您不会创建单个
写入
,而是创建一个方法,该方法可以为定义了
写入
的任何类型创建写入

您说过希望避免
javaconversion
,但正如您所看到的,这很困难,因为
JsArray
要求一个
Seq[JsValue]
,所以您需要以某种方式构造一个scala
Seq

我在这里展示的内容或多或少相当于使用
asScala
将java
List
转换为scala
mutable.Buffer
并使用
可遍历的
的默认
写入

请注意,转换可能没有您想象的那么广泛,它们只是创建一个包装器,不涉及复制

这是我能提供的最好的性能

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)
  }
}
implicit def jListWrites[A:Writes]=新写入[java.util.List[A]]{
重写def写入(o:util.List[A]):JsValue={
val buffer=新数组[JsValue](o.size)
变量i=0
而(i
1000000
Int
s需要29毫秒,而直接实现需要39毫秒。请注意,
Int
易于转换,如果对象更复杂,则加速比会更小


转换20000个
案例类C(num:Int,n2:Int,s:String)
会得到相同的结果(直截了当会更快0.14毫秒)。

谢谢。这正是我想要的。