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
Running Selenium Scripts with Jmeter
Is Doing a Lot in Constructors Bad
How to Compile Multiple Java Source Files in Command Line
Lists with Wildcards Cause Generic Voodoo Error
Are There Any Other Java Libraries for Bonjour/Zeroconf Apart from Jmdns
What Is the Equivalent of Java Static Final Fields in Kotlin
Using an Instance of an Object as a Key in Hashmap, and Then Access It with Exactly New Object
Convert Bufferedinputstream into Image
What Is an "Internal Address" in Java
How to Compile Java to Native Code
Eclipse Memory Settings When Getting "Java Heap Space" and "Out of Memory"
How to Get an Enum Based on the Value of Its Field
Invokeandwait Method in Swingutilities