类型转换:将[String,String]映射到Map [String,Object]

时间:2017-10-10 22:19:57

标签: java scala sbt scala-collections

我是scala的新手,当我编译我的SBT项目时,我看到了这个例外:

[error] C:\dev\reactive-rabbit\src\main\scala\io\scalac\amqp\impl\RabbitConnection.scala:58: type mismatch;
[error]  found   : Map[String,String] (in scala.collection.immutable)
[error]  required: Map[String,Object] (in java.util)
[error]     future(onChannel(_.exchangeBind(destination, source, routingKey, arguments)))
[error]                                                                      ^

我最近将已弃用的JavaConversions库替换为JavaConverters。我的代码看起来像这样:

import scala.collection.JavaConvertors._
override def exchangeBind(destination: String, source: String, routingKey: String,
                        arguments: Map[String, String]) =
    future(onChannel(_.exchangeBind(destination, source, routingKey, arguments)))
      .map(_ ⇒ Exchange.BindOk())

我查看了onChannel()的合同,其arguments参数需要类型Map[String, Object](java集合),但我传递的是Map [String,String](scala immutable)。如何在将此参数传递给方法时更改此参数的数据类型?感谢。

2 个答案:

答案 0 :(得分:1)

Scala Map在值类型参数中是协变的,因此Map[String, String]已经Map[String, Object],不需要mapmapValues。您可以将其分配给具有所需类型的val或使用类型归属:arguments: Map[String, Object]。然后拨打asJava

(arguments: Map[String, Object]).asJava

请注意,在其他答案不必要的情况下使用asInstanceOf是不好的样式:如果稍后更改类型,编译器无法告诉您需要更改代码的位置。

答案 1 :(得分:0)

使用JavaConverters而不是JavaConversions(不推荐使用),并将String映射到Object以防止出现以下错误:

<console>:19: error: type mismatch;
 found   : java.util.Map[String,String]
 required: java.util.Map[String,Object]
Note: String <: Object, but Java-defined trait Map is invariant in type V.
You may wish to investigate a wildcard type such as `_ <: Object`. (SLS 3.2.10)
       javaMap = Map[String,String]().asJava

scala> :paste
// Entering paste mode (ctrl-D to finish)

import scala.collection.JavaConverters._

var javaMap: java.util.Map[String,Object] = new java.util.HashMap()
javaMap.put("key", "value")

println(javaMap)

javaMap = Map[String,String]("new_key" -> "new_value").map{case (k,v) => (k, v.asInstanceOf[Object])}.asJava

// Exiting paste mode, now interpreting.

{key=value}
import scala.collection.JavaConverters._
javaMap: java.util.Map[String,Object] = {new_key=new_value}
javaMap: java.util.Map[String,Object] = {new_key=new_value}

scala>