3

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!

2 Answers 2

4

Try this:

import collection.JavaConverters._
val javaMap = scalaMap.mapValues(_.asJava).asJava

It does the job in two steps:

  1. first converts Map[String,Seq[String]] to Map[String,java.util.List[String]]

  2. then the whole map to Java Map: java.util.Map[String,java.util.List[String]].

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks that works great. I knew there was some slick functional way to do this!
Even better. Thanks again for your help.
1

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 demonstration

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}

Comments

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.