1

I am trying to convert a java.util.List to a Scala list. There are many possibilities presented in post 674713 so I would like to know which one is the the best. I am using Play 2.1.1. My model is :

case class Page[T](
    var data: java.util.List[T],
    var previous: String,
    var next: String,
    var totalPageCount: Int)(implicit val tWrites: Writes[T])

object Page {

    implicit def pageWrites[T: Writes]: Writes[Page[T]] = (
        (__ \ 'data).write[java.util.List[T]] and
        (__ \ 'previous).write[String] and
        (__ \ 'next).write[String] and
        (__ \ 'totalPageCount).write[Int])(unlift(Page.unapply[T]))
}

This code does not work because I need to add a writer for generic java.util.List[T] type.

I have added this to my object Page :

implicit def listWrites[T](implicit fmt: Writes[T]): Writes[List[T]] = new Writes[List[T]] {
    def writes(ts: List[T]) = JsArray(ts.map(t => Json.toJson(t)(fmt)))
}

But this generates an error when executing my project ("MatchError: null" on listWrites). Therefore I would like to convert my java.util.List to a Scala one to avoid using this writer that does not work. Any solution ?

Christophe
  • 107
  • 2
  • 8
  • possible duplicate of [How to Convert java util list to Scala list](http://stackoverflow.com/questions/16162090/how-to-convert-java-util-list-to-scala-list) – Peter Apr 22 '14 at 14:16

1 Answers1

5

As a default I'd start of with:

import scala.collection.JavaConverters._
data.asScala //var data: java.util.List[T]

This will return a buffer, as the JavaList is mutable. To convert to a List you will have to also call the toList method

data.asScala.toList //List[T]

This would make the conversion explicit, is short readable and is bound to work throughout different versions because it's part of the standard library.

Here is a solution by adding an implicit Conversion. You now should be able to call data.toScalaList if you import the conversion.

object Example {
  implicit class Data[T](data: java.util.List[T]) {
    import scala.collection.JavaConverters._
    def toScalaList: List[T] = data.asScala.toList
  }
}

//just import it with
import Example._
Andreas Neumann
  • 10,734
  • 1
  • 32
  • 52
  • Works for me: scala> new java.util.LinkedList[String].asScala res3: scala.collection.mutable.Buffer[String] = Buffer(). WHich Version of Scala are you using. The example is based on 2.10. – Andreas Neumann Apr 22 '14 at 14:29
  • I am working with Play 2.1.1. So I think it is Scala 2.1 too. – Christophe Apr 22 '14 at 14:34
  • The converters are part of Scala since 2.8. Have a look at your build.sbt. THere should be a key scalaVersion := which denotes the version. – Andreas Neumann Apr 22 '14 at 14:37
  • I don't have a build.sbt (as I am using Play maybe ?) but I have the converters as I have access to asScalaMapConverters method for example which is part of JavaConverters. I am just missing asScala. – Christophe Apr 22 '14 at 14:49
  • I have "AsJava" with an uppercase so I am not sure this is what I should use. And in fact when I use it I don't have the toList method on it. – Christophe Apr 22 '14 at 14:54
  • I added another Example. Perhaps this works for you. – Andreas Neumann Apr 22 '14 at 17:47
  • Your first solution works fine. I was trying to transform the java.util.List in a Scala immutable one in my model (in the constructor parameters) but in fact this does not work. So now I am using a Scala list in my model and when I need to convert it in my project I use the asScala.toList (also adding the import you specified). Thanks for your help ! – Christophe Apr 23 '14 at 08:19