Converting Java collections to Scala collections from Java
July 7, 2016
Converting between Java and Scala collections from Scala code is remarkably easy -
scala> import scala.collection.JavaConverters._
scala> val jList = new java.util.ArrayList[String]
scala> jList.asScala
scala.collection.mutable.Buffer[String] = Buffer()
scala> jList.asScala.toSeq
Seq[String] = Buffer()
scala> val sList = List[String]()
List[String] = List()
scala> sList.asJava
java.util.List[String] = []
scala> val jMap = new java.util.HashMap[String,String]
scala> jMap.asScala
res6: scala.collection.mutable.Map[String,String] = Map()
scala> jMap.asScala.toMap
res7: scala.collection.immutable.Map[String,String] = Map()
But doing the same from Java is a little more difficult. We can see what Scala is doing under the hood by using reify
then use the same approach from Java -
scala> import scala.reflect.runtime.{universe => u}
scala> println(u.reify { jList.asScala.toSeq })
Expr[Seq[String]](
JavaConverters.asScalaBufferConverter($read.jList).asScala.toSeq
)
scala> println(u.reify { jMap.asScala.toMap })
Expr[scala.collection.immutable.Map[String,String]](
JavaConverters.mapAsScalaMapConverter(
$read.$iw.$iw.$iw.$iw.jMap
).asScala.toMap(Predef.$conforms)
)
In order to pull this off in Java, we can just follow the calls presented in the desugared ASTs from above -
import java.util.*;
import scala.Predef;
import scala.collection.Seq;
import scala.collection.JavaConverters;
public class Main {
public static void main(String args[]) {
// Java collections.
List<String> jList = new ArrayList<>();
Map<String, String> jMap = new HashMap<>();
// Convert to Scala collections.
Seq<String> sList = JavaConverters.asScalaBufferConverter(xs).asScala().toSeq();
Map<String, String> sMap =
JavaConverters.mapAsScalaMapConverter(jMap).asScala().toMap(Predef.$conforms());
}
}