Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using java Map in scala

Tags:

scala

I am thoroughly confused by this behavior in the Scala REPL:

scala> import java.util.Map
import java.util.Map

scala> import java.util.HashMap
import java.util.HashMap

scala> val jMap:java.util.Map[String,Int]=new HashMap[String,Int]("first"->1,"second" -> 2)

<console>:12: error: type mismatch;
found   : (String, Int)
required: Float
   val jMap =new HashMap[String,Int]("first"->1,"second" -> 2)
                                                                     ^
<console>:12: error: type mismatch;
found   : (String, Int)
required: Float
   val jMap=new HashMap[String,Int]("first"->1,"second" -> 2)
                                                                                  ^

Can someone help explain what's going on here ?

like image 400
femibyte Avatar asked Dec 02 '22 14:12

femibyte


1 Answers

java.util.HashMap does not provide capability to construct the map by passing a vararg of (K, V), but there is a two-arg constructor accepting initialCapacity: Int and loadFactor: Float, that's why you're getting the compile error about a Float being required.

(updated for scala 2.13+) The idiomatic approach in Scala would be to just use Scala immutable maps (no imports required):

val map = Map("first" -> 1, "second" -> 2).asJava

If your Scala code works with a Java library that returns a java.util.Map, you can convert it into a Scala map explicitly by using scala.jdk.CollectionConverters like so:

import scala.jdk.CollectionConverters._

val javaMap: java.util.Map[String, String] = // ...
val map = javaMap.asScala

// or vice versa if you need to pass it into the Java API

val javaMap = Map("first" -> 1, "second" -> 2).asJava

Note that asScala is just a wrapper to the underlying Java map (so if that one is mutable, the wrapped map will also be mutable) and is an instance of scala.collection.Map. In order to be fully idiomatic and benefit from Scala's immutability guarantees, you might need to add another .toMap at the end that will convert it to scala.collection.immutable.Map (which is the default Map).

If you use scala 2.12 or older, instead of scala.jdk.CollectionConverters._ import scala.collection.JavaConverters._.

like image 175
Sergey Avatar answered Jan 06 '23 18:01

Sergey