Bry*_*unt 7 java scala covariance scala-java-interop
我正在使用asynchttpclient.构建参数时,将java.util.Map传递给setParameters方法.
(Java)签名如下所示:
setParameters(Map<String,Collection<String>);
Run Code Online (Sandbox Code Playgroud)
真实的一天1.但哇,我正试图从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
Run Code Online (Sandbox Code Playgroud)
这是错误信息,
Run Code Online (Sandbox Code Playgroud)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
Run Code Online (Sandbox Code Playgroud)
并收到以下可爱的错误消息作为回应.
Run Code Online (Sandbox Code Playgroud)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
Run Code Online (Sandbox Code Playgroud)
但这产生了以下结果
此行的多个标记 - 重载方法值setParameters with alternatives:(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
Run Code Online (Sandbox Code Playgroud)
好吧,第一条错误信息明确表示 - 因为它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)
Run Code Online (Sandbox Code Playgroud)