Scala对Java集合API不感兴趣?

7
我将使用asynchttpclient。在构建参数时,需要将java.util.Map传递给setParameters方法。
Java签名如下:
setParameters(Map<String,Collection<String>);

真正的一天工作。但是哇,我试图从Scala中调用它,但是我无论如何都不能创建一个与该签名匹配的集合。

这是我到目前为止制造的混乱。

var m:java.util.Map[java.lang.String,java.util.Collection[java.lang.String]] = new java.util.HashMap[java.lang.String,java.util.HashSet[java.lang.String]]()
val req = new RequestBuilder().setUrl("http://localhost:1234/").setParameters(m).build

以下是错误信息:

Multiple markers at this line
- type mismatch; found : java.util.HashMap[java.lang.String,java.util.HashSet[java.lang.String]] required: 
 java.util.Map[java.lang.String,java.util.Collection[java.lang.String]] Note: java.util.HashSet[java.lang.String] <: java.util.Collection[java.lang.String], but Java-defined 
 **trait Map is invariant in type V. You may wish to investigate a wildcard type such as `_ <: java.util.Collection[java.lang.String]`. (SLS 3.2.10)**
- type mismatch; found : 

好的,我觉得我并没有做什么特别复杂的事情,但让我们试试编译器建议吧...

所以我将其更改为以下内容

 var m:java.util.Map[java.lang.String,_ <: java.util.Collection[java.lang.String]] = new java.util.HashMap[java.lang.String,java.util.HashSet[java.lang.String]]()
 val req = new RequestBuilder().setUrl("http://localhost:1234/").setParameters(m).build

然后你会收到以下美丽的错误消息。

Multiple markers at this line
    - overloaded method value setParameters with alternatives: (com.ning.http.client.FluentStringsMap)com.ning.http.client.RequestBuilder <and> 
     (java.util.Map[java.lang.String,java.util.Collection[java.lang.String]])com.ning.http.client.RequestBuilder cannot be applied to (java.util.Map[java.lang.String,_$1])
回到基础知识,我也想提及我的第一个尝试如下所示。
   import scala.collection.JavaConverters._
   var m = Map[String,Set[String]]()
   val req = new RequestBuilder().setUrl("http://localhost:1234/").setParameters(m.asJava).build

但是这产生了以下结果:

此行有多个标记 - 方法值setParameters的重载版本: (com.ning.http.client.FluentStringsMap)com.ning.http.client.RequestBuilder (java.util.Map[java.lang.String,java.util.Collection[java.lang.String]])com.ning.http.client.RequestBuilder不能应用于(java.util.Map[String,Set[String]])

编辑,感谢__0,现在它已经正常工作。这是我的最终代码:

 def buildReqMap(in: Map[String, String]) = {
   import java.util.{ Map => JMap, Collection => JColl, HashMap => JHashM, HashSet => JHashS }
   val m: JMap[String, JColl[String]] =
     new JHashM[String, JColl[String]]()
   in.fold(m) { (a, b) =>
     {
       val s = new JHashS[String]()
       s.add(b.asInstanceOf[String])
       m.put(a.asInstanceOf[String], s)
       m
     }
   }
   m
 }

 def main(args: Array[String]): Unit = {
   val m = buildReqMap(
     Map(
       ("delimited" -> "length"),
       ("track" -> "binarytemple,music,kittens")))

   val req = new RequestBuilder().setUrl("http://localhost:1234/").setParameters(m).build
   val fut = asyncHttpClient.executeRequest(req, handler).get
1个回答

9

首先,第一个错误信息明确表明——由于java.util.Map是可变的,它无法处理变异性。因此,您不能将Map [_,Set [_]]强制转换为Map [_,Collection [_]]

val m: java.util.Map[String, java.util.Collection[String]] = 
   new java.util.HashMap[String,java.util.Collection[String]]()
val s = new java.util.HashSet[String]()
s.add("welt")
m.put("hallo", s)

是的,我很困惑,认为我需要指定一个实现,而不是接口,这是初学者的错误。 - Bryan Hunt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接