Java/Scala (deep) collections interoperability

java, scala

Solution

The method for doing this has changed from 2.7 to 2.8. Retronym's method works well for 2.8. For 2.7, you'd instead use `collections.jcl` like so:

object Example {
  import scala.collection.jcl

  // Build the example data structure
  val row1 = new java.util.ArrayList[Double]()
  val row2 = new java.util.ArrayList[Double]()
  val mat = new java.util.ArrayList[java.util.ArrayList[Double]]()
  row1.add(1.0) ; row1.add(2.0) ; row2.add(3.0) ; row2.add(4.0)
  mat.add(row1) ; mat.add(row2)
  val named = new java.util.HashMap[String,java.util.ArrayList[java.util.ArrayList[Double]]]
  named.put("matrix",mat)

  // This actually does the conversion
  def asScala(thing: java.util.HashMap[String,java.util.ArrayList[java.util.ArrayList[Double]]]) = {
    Map() ++ (new jcl.HashMap(thing)).map(kv => {
      ( kv._1 ,
        (new jcl.ArrayList(kv._2)).map(al => {
          (new jcl.ArrayList(al)).toArray
        }).toArray
      )
    })
  }
}

So, the general idea is this: from the outside in, wrap the Java collection in a Scala equivalent, then use map to wrap everything in the next level. If you want to convert between Scala representations, do that on the way out (here, the `.toArray` at the ends).

And here you can see the example working:

scala> Example.named
res0: java.util.HashMap[String,java.util.ArrayList[java.util.ArrayList[Double]]] = {matrix=[[1.0, 2.0], [3.0, 4.0]]}

scala> val sc = Example.asScala(Example.named)
sc: scala.collection.immutable.Map[String,Array[Array[Double]]] = Map(matrix -> Array([D@1ea817f, [D@dbd794))

scala> sc("matrix")(0)
res1: Array[Double] = Array(1.0, 2.0)

scala> sc("matrix")(1)
res2: Array[Double] = Array(3.0, 4.0)

Problem

Could you please share your opinion on what is the most elegant and/or efficient way of converting a ``` java.util.HashMap[ java.lang.String, java.util.ArrayList[ java.util.ArrayList[java.lang.Double] ] ] (all of the objects are from java.util or java.lang) ``` to ``` Map[ String, Array[ Array[Double] ] ] (all of the objects are from scala) ``` Thanks, -A

Original source