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 ?

1

1 Answer 1

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._
Sign up to request clarification or add additional context in comments.

7 Comments

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.
I am working with Play 2.1.1. So I think it is Scala 2.1 too.
The converters are part of Scala since 2.8. Have a look at your build.sbt. THere should be a key scalaVersion := <VERSION NUMBER> which denotes the version.
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.
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.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.