Convert Java.Util.Hashmap to Scala.Collection.Immutable.Map in Java

Convert Java map into Scala immutable map in Java code with Scala-2.13

You have a very simple solution in Scala 2.13:

scala.collection.immutable.Map<Integer, String> scalaMap =
scala.collection.immutable.Map.from(scala.jdk.CollectionConverters.MapHasAsScala(javaMap).asScala());

Convert Java Map to Scala Map

Edit: the recommended way is now to use JavaConverters and the .asScala method:

import scala.collection.JavaConverters._
val myScalaMap = myJavaMap.asScala.mapValues(_.asScala.toSet)

This has the advantage of not using magical implicit conversions but explicit calls to .asScala, while staying clean and consise.


The original answer with JavaConversions:

You can use scala.collection.JavaConversions to implicitly convert between Java and Scala:

import scala.collection.JavaConversions._
val myScalaMap = myJavaMap.mapValues(_.toSet)

Calling mapValues will trigger an implicit conversion from the java Map to a scala Map, and then calling toSet on the java collection with implicitly convert it to a scala collection and then to a Set.

By default, it returns a mutable Map, you can get an immutable one with an additional .toMap.

Short-ish example:

scala> val a: java.util.Map[String, java.util.Collection[String]] = new java.util.HashMap[String, java.util.Collection[String]]
a: java.util.Map[String,java.util.Collection[String]] = {}

scala> val b = new java.util.ArrayList[String]
b: java.util.ArrayList[String] = []

scala> b.add("hi")
res5: Boolean = true

scala> a.put("a", b)
res6: java.util.Collection[String] = []

scala> import scala.collection.JavaConversions._
import scala.collection.JavaConversions._

scala> val c = a.mapValues(_.toSet)
c: scala.collection.Map[String,scala.collection.immutable.Set[String]] = Map(a -> Set(hi))

scala> c.toMap
res7: scala.collection.immutable.Map[String,scala.collection.immutable.Set[String]] = Map(a -> Set(hi))

How to convert a java Map to immutable Scala map via java code?

I changed conforms to $conforms and it now runs find in both Intellij and the command line but Intellij still give a red line under JavaConverters.mapAsScalaMapConverter(m).asScala().toMap( that says cannot access scala.Predef.$less$colon$colon.

private   <A,B> scala.collection.immutable.Map<A, B> toScalaMap(Map<A, B> m) {
return JavaConverters.mapAsScalaMapConverter(m).asScala().toMap(
Predef.$conforms()
);
}

How to convert a java HashMap to immutable Scala map via java code?

You can use JavaConverters to do this

import java.util.HashMap;
import scala.Predef;
import scala.Tuple2;
import scala.collection.JavaConverters;
import scala.collection.immutable.Map;

public class ToScalaTest {
public static <A, B> Map<A, B> toScalaMap(HashMap<A, B> m) {
return JavaConverters.mapAsScalaMapConverter(m).asScala().toMap(
Predef.<Tuple2<A, B>>conforms()
);
}

public static HashMap<String, String> test() {
HashMap<String, String> m = new HashMap<String, String>();
m.put("a", "Stackoverflow");
return m;
}
}

We can show that this works in the Scala REPL

scala> val jm: java.util.HashMap[String, String] = ToScalaTest.test
jm: java.util.HashMap[String,String] = {a=Stackoverflow}

scala> val sm: Map[String, String] = ToScalaTest.toScalaMap(jm)
sm: Map[String,String] = Map(a -> Stackoverflow)

You can of course just call this methods easily from java code

How do I convert a java.util.Map to scala.collection.immutable.Map in Java?

Getting an immutable Scala map is a little tricky because the conversions provided by the collections library return all return mutable ones, and you can't just use toMap because it needs an implicit argument that the Java compiler of course won't provide. A complete solution with that implicit argument looks like this:

import scala.collection.JavaConverters$;
import scala.collection.immutable.Map;

public class Whatever {
public <K, V> Map<K, V> convert(java.util.Map<K, V> m) {
return JavaConverters$.MODULE$.mapAsScalaMapConverter(m).asScala().toMap(
scala.Predef$.MODULE$.<scala.Tuple2<K, V>>conforms()
);
}
}

Writing conversions in Java is a little cleaner with JavaConversions, but on the Scala side essentially everyone hopes that piece of crap will get deprecated as soon as possible, so I'd avoid it even here.

convert java.util.Map[String, Object] to scala.collection.immutable.Map[String, Any]

As VonC says, scala.collections.JavaConversion supports mutable collections only, but you don't have to use a separate library. Mutable collections are derived from TraversableOnce which defines a toMap method that returns an immutable Map:

import scala.collection.JavaConversions._

val m = new java.util.HashMap[String, Object]()
m.put("Foo", java.lang.Boolean.TRUE)
m.put("Bar", java.lang.Integer.valueOf(1))

val m2: Map[String, Any] = m.toMap
println(m2)

This will output

Map(Foo -> true, Bar -> 1)


Related Topics



Leave a reply



Submit