Reputation: 1195
I am new to Scala, trying to integrate some existing Java code with Scala-specific functionality in the Play Framework.
val scalaMap = getScalaMap() // returns Map[String,Seq[String]]
What is a nice clean way to convert scalaMap to use Java collections?
val javaMap = ??? // java.util.Map<String,List<String>>
It looks like I want to use JavaConversions, but I'm not sure how to chain together the nested collections. Thanks!
Upvotes: 3
Views: 939
Reputation: 52681
Do not use mapValues
. Use map
:
import collection.JavaConverters._
val javaMap = scalaMap.map { case (k,v) => (k, v.asJava) }.asJava
Using mapValues
will cause the inner-Map to be re-converted every time it is accessed.
A Scala Map
scala> val scalaMap = Map(1 -> Map('a -> "A"), 2 -> Map('b -> "B"))
Converting to a Java Map (but print something each time we convert the inner-Map)
scala> val javaMapBad = scalaMap.mapValues(v => { println("evaluating "+v); v.asJava }).asJava
evaluating Map('a -> A)
evaluating Map('b -> B)
javaMapBad: java.util.Map[Int,java.util.Map[Symbol,java.lang.String]] = {1={'a=A}, 2={'b=B}}
scala> javaMapBad.get(1)
evaluating Map('a -> A) // Re-conversion!
res0: java.util.Map[Symbol,java.lang.String] = {'a=A}
scala> javaMapBad.get(1)
evaluating Map('a -> A) // Re-conversion!
res1: java.util.Map[Symbol,java.lang.String] = {'a=A}
The right way to do it
scala> val javaMapGood = scalaMap.map{case (k,v) => {println("evaluating "+v); (k,v.asJava)}}.asJava
evaluating Map('a -> A)
evaluating Map('b -> B)
javaMapGood: java.util.Map[Int,java.util.Map[Symbol,java.lang.String]] = {1={'a=A}, 2={'b=B}}
scala> javaMapGood.get(1) // no re-conversion
res6: java.util.Map[Symbol,java.lang.String] = {'a=A}
scala> javaMapGood.get(1) // no re-conversion
res7: java.util.Map[Symbol,java.lang.String] = {'a=A}
Upvotes: 1
Reputation: 340733
Try this:
import collection.JavaConverters._
val javaMap = scalaMap.mapValues(_.asJava).asJava
It does the job in two steps:
first converts Map[String,Seq[String]]
to Map[String,java.util.List[String]]
then the whole map to Java Map
: java.util.Map[String,java.util.List[String]]
.
Upvotes: 4