Ответ 1
Есть несколько способов сделать это, только некоторые из них появились в ответах до сих пор.
Метод первый: Так как java.util.HashMap
имеет конструктор HashMap(Map<? extends K,? extends V> m)
, вы можете передать ему действительную карту Java. И вы можете сделать это тривиально с помощью Scala полезно JavaConversions
:
scala> import scala.collection.JavaConversions._
import scala.collection.JavaConversions._
scala> val myMap = Map(1->"Hi",2->"Bye")
myMap: scala.collection.immutable.Map[Int,java.lang.String] = Map((1,Hi), (2,Bye))
scala> val jmap = new java.util.HashMap[Int,String](myMap) // Need explicit types
jmap: java.util.HashMap[Int,String] = {1=Hi, 2=Bye}
Недостатки здесь в том, что у вас уже есть карта Scala (немного расточительная, если вы просто собираетесь создать Java-вариант), и что вам нужно указать типы. Но он компактный и безболезненный.
Метод второй:. Кроме того, вы можете создать новый блок кода в качестве оператора объявления, поэтому вам даже не нужно иметь JavaConversions
:
scala> val jmap2 = {
| val x = new java.util.HashMap[Int,String]
| for ((k,v) <- List(1->"Howdy",2->"partner")) x.put(k,v)
| x
| }
jmap2: java.util.HashMap[Int,String] = {1=Howdy, 2=partner}
Чуть менее компактный, но полностью общий, а также эффективный (или неэффективный), как вы его делаете.
Метод третий:. Кроме того, вы можете создать анонимный подкласс HashMap, если он будет иметь подкласс (т.е. .getClass
не вернет java.util.HashMap
)), и используйте инициализатор для установки ваших значений:
scala> val jmap3 = new java.util.HashMap[Int,String] {
| put(1,"Yo"); put(2,"bro")
| }
jmap3: java.util.HashMap[Int,String] = {1=Yo, 2=bro}
scala> jmap3.getClass.getName
res0: java.lang.String = $anon$1
scala> jmap3.getClass.getSuperclass.getName
res1: java.lang.String = java.util.HashMap
Недостатком, конечно же, является подкласс HashMap
, а не HashMap
, но он более компактный, чем версия с назначением-из-кода, поскольку вам не нужно назначать новую карту a val.
Метод четыре: И, наконец, вы можете создать метод, который сделает то, что вы хотите, и назовите его:
scala> def newJHM[A,B](kv: Iterable[(A,B)]) = {
| val jhm = new java.util.HashMap[A,B]
| kv.foreach(i => jhm.put(i._1,i._2))
| jhm
| }
newJHM: [A,B](kv: Iterable[(A, B)])java.util.HashMap[A,B]
scala> val jmap4 = newJHM(Seq(1->"Bye",2->"Now")) // Type inference now works
jmap4: java.util.HashMap[Int,java.lang.String] = {1=Bye, 2=Now}
Это едва менее компактно, чем другие, и правильные типы, без необходимости указывать их, поэтому это может быть привлекательным выбором, если вы делаете это более одного раза.
P.S. Просто для удовольствия я показал множество способов получить некоторые пары "ключ-значение" на карте, но они не специфичны для данного метода (кроме # 1, для которого требуется карта). Смешайте и согласитесь по своему усмотрению.