如何从Scala代码实时填充java.util.HashMap? [英] How to populate java.util.HashMap on the fly from Scala code?

查看:468
本文介绍了如何从Scala代码实时填充java.util.HashMap?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是ScalaTest的单元测试java代码,希望在它声明的同一个语句中填充一个java.util.HashMap。是否有可能在Scala中做到这一点?

解决方案

有很多不同的方法可以实现这一点,出现在答案到目前为止。



方法一: java.util.HashMap 具有构造函数 HashMap(Map <?extends K ,? extends V> m),您可以将它传递给一个有效的Java Map。你可以用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)//需要显式类型
jmap:java.util.HashMap [Int,String] = {1 = Hi,2 = Bye}

这里的缺点是你必须已经有一个Scala地图(如果你只是想创建一个Java可能),并且你必须指定类型。但它非常紧凑且无痛苦。

方法二:或者,您可以创建一个新的代码块作为声明语句,所以您不需要甚至需要有 JavaConversions 可用:

  scala> val jmap2 = {
| val x =新的java.util.HashMap [Int,String]
| ((k,v)< - 列表(1->你好,2->伙伴))x.put(k,v)
| x
| }
jmap2:java.util.HashMap [Int,String] = {1 = Howdy,2 = partner}

稍微不那么紧凑,但是完全一般,并且像您所关心的那样有效(或低效)。

方法三: / strong>另外,只要可以创建一个子类(即 .getClass 不会返回 java),就可以创建一个HashMap的匿名子类。 .util.HashMap ),并使用初始化程序设置您的值:

  scala> val jmap3 =新的java.util.HashMap [Int,String] {
|放(1, 哟);把(2,兄弟)
| }
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 的子类,但它更紧​​凑因为您不需要将新地图分配给VAL,所以比代码块分配版本更好。



方法四:最后,当然,你可以创建一个方法来实现你想要的,然后调用它:

  scala> def newJHM [A,B](kv:Iterable [(A,B)])= {
| val jhm =新的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))//现在类型推断工作
jmap4:java.util.HashMap [Int,java.lang.String] = {1 = Bye,2 = Now}

类型正确无需指定它们,因此如果您不止一次地执行此操作,它可能是一个吸引人的选择。



PS为了好玩,我已经展示了多种获取键值对的方法,但它们并不特定于给定的方法(除了#1需要地图)。根据您的喜好混合搭配。


I am unit testing java code from ScalaTest and would like to populate a java.util.HashMap within the same statement it gets declared. Is it possible to do this in Scala?

解决方案

There are a bunch of different ways to accomplish this, only some of which have appeared in the answers thus far.

Method One: Since java.util.HashMap has the constructor HashMap(Map<? extends K,? extends V> m), you could pass it a valid Java Map. And you can do this trivially with Scala's helpful 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}

The downsides here are that you have to already have a Scala map (slightly wasteful if you're just going to create a Java one, perhaps), and that you have to specify the types. But it's compact and painless.

Method Two: Alternatively, you can create a new code block as the declaration statement, so you don't even need to have JavaConversions available:

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}

Slightly less compact, but completely general, and as efficient (or inefficient) as you care to make it.

Method Three: Also, you can create an anonymous subclass of HashMap as long as it's okay to have a subclass (i.e. .getClass won't return java.util.HashMap), and use the initializer to set your values:

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

The downside is, of course, that it's a subclass of HashMap rather than HashMap, but it's more compact than the assignment-from-code-block version since you don't need to assign the new map to a val.

Method Four: And finally, of course, you can create a method that does what you want and call it instead:

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}

This is barely less compact than the others and gets the types correct without you having to specify them, so it can be an appealing choice if you're doing this more than once.

P.S. Just for fun, I've shown a variety of ways of getting some key-value pairs into the map, but they're not specific to a given method (except for #1 which requires a map). Mix and match at your preference.

这篇关于如何从Scala代码实时填充java.util.HashMap?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆