Scala, не нравится API коллекций Java?

Я использую асинхронный клиент. При создании параметров 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. Коллекция[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

person Bryan Hunt    schedule 25.07.2012    source источник


Ответы (1)


Что ж, первое сообщение об ошибке дало понять, что, поскольку 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)
person 0__    schedule 25.07.2012
comment
Да, я запутался, думая, что мне нужно указать реализацию, а не интерфейс, ошибка новичков. - person Bryan Hunt; 25.07.2012