A Java API returns a java.util.Map<java.lang.String,java.lang.Boolean>
;. I would like to put that into a Map[String,Boolean]
So imagine we have:
var scalaMap : Map[String,Boolean] = Map.empty
val javaMap = new JavaClass().map() // Returns java.util.Map<java.lang.String,java.lang.Boolean>
You can't do Map.empty ++ javaMap
, because the ++ method does not know about Java maps. I tried:
scalaMap = Map.empty ++ new collection.jcl.MapWrapper[String,Boolean] {
override def underlying = javaMap
}
and:
scalaMap = Map.empty ++ new collection.jcl.MapWrapper[java.lang.String,java.lang.Boolean] {
override def underlying = javaMap
}
These both fail to compile, because of the generics - java.lang.String
is not the same as a scala String.
Is there a good way of doing this, short of copying the map manually?
EDIT: Thanks, all good answers, I learned a lot from all of them. However, I made a mistake by posting a simpler problem here than the one I actually have. So, if you allow me, I'll generalise the question - What the API actually returns is
java.util.Map<java.lang.String, java.util.Map<SomeJavaEnum,java.lang.String>>
And I need to move this to Map[String, Map[SomeJavaEnum,String]]
It probably does not seem like too much of a complication, but it adds an extra level of type erasure, and the only way I found of moving this to a Scala map was deep-copying it (using some of the techniques you suggested below). Anyone any hints? I kind of solved my problem by defining an implicit conversion for my exact types, so at least the ugliness is hidden in its own trait, but still feels a bit clumsy deep copying the lot.
If you just want a mutable HashMap , you can just use x. toMap in 2.8 or collection. immutable. Map(x.
Map class explicitly. If you want to use both mutable and immutable Maps in the same, then you can continue to refer to the immutable Map as Map but you can refer to the mutable set as mutable. Map. While defining empty map, the type annotation is necessary as the system needs to assign a concrete type to variable.
Scala map is a collection of key/value pairs. Any value can be retrieved based on its key. Keys are unique in the Map, but values need not be unique. HashMap implements immutable map and uses hash table to implement the same.
You can convert it into two list objects one which contains key values and the one which contains map values separately. Create a Map object. Create an ArrayList of integer type to hold the keys of the map. In its constructor call the method keySet() of the Map class.
At least with Scala 2.9.2 there's an easier way with the collections conversions: import "import collection.JavaConversions._" and use "toMap".
Example:
// show with Java Map:
scala> import java.util.{Map=>JMap}
scala> val jenv: JMap[String,String] = System.getenv()
jenv: java.util.Map[String,String] = {TERM=xterm, ANT_OPTS=-Xmx512m ...}
scala> jenv.keySet()
res1: java.util.Set[String] = [TERM, ANT_OPTS...]
// Now with Scala Map:
scala> import collection.JavaConversions._
scala> val env: Map[String,String] = System.getenv.toMap // <--- TADA <---
env: Map[String,String] = Map(ANT_OPTS -> -Xmx512m, TERM -> xterm ...)
// Just to prove it's got Scala functionality:
scala> env.filterKeys(_.indexOf("TERM")>=0)
res6: scala.collection.immutable.Map[String,String] = Map(TERM -> xterm,
TERM_PROGRAM -> iTerm.app, ITERM_PROFILE -> Default)
It works fine with a java.util.map of String to Boolean.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With