2016-03-23 12 views
0

Wenn ich eine java.util.Map[String,Java.util.Map] für den ersten Anruf habe, wird korrekt überladene Methode heißt: toScala(java.util.Map[_,_]). Im Aufruf von mapValues ​​wird jedoch die Funktion toScala(other:Any) aufgerufen. Wie vermeide ich das? Ich würde zu Scala mit einem Java-Objekt wie Map, List, Int, String aufrufen. Die Karte kann einen anderen java.util.Map/java.util.List/ String/Int als einen ihrer Werte enthalten. Ebenso kann die Liste auch eine andere java.util.List/ String/ Int als Mitglieder enthaltenScala Overloading Problem

private def toScala(map:java.util.Map[_,_]) : Any = { 
    map match { 
     case null => Map.empty 
     case _ => map.asScala.mapValues(toScala).toMap 
    } 
    } 

    private def toScala(list:java.util.List[_]) : Any = { 
    list match { 
     case null => List.empty 
     case _ => list.asScala.map(toScala).toList 
    } 
    } 

    private def toScala(other:Any) : Any = { 
    other match { 
     case null => None 
     case _ => other 
    } 
    } 
+0

Verwenden Sie eine korrekte Typen statt Platzhalter und 'Irgendein'. Ich bin mir nicht sicher, was genau Sie tun möchten, aber typeclasses könnte die Lösung sein. –

+0

Aber ich kann das nicht tun, da meine Map Werte der Typen List, String, Int, Map usw. enthalten könnte. Ich versuche ScalaAppconfigWrapper über JavaAppConfigWrapper zu erstellen. – bugs

+0

Bitte bearbeiten Sie Ihre Frage, um uns zu zeigen, wie Sie den Code aufrufen. Was Sie erwarten, klar zu lösen. –

Antwort

0

Vielleicht hilft Ihnen:

private def toScala(v: Any): Any = vmatch { 
  case null => throw new NullPointerException("null value encountered while converting Java to Scala") 
  case m: java.util.Map[_, _] => m.asScala.mapValues(toScala).toMap 
  case m: java.util.List[_] => m.asScala.map(toScala).toMap 
  case m: java.util.Set[_] => m.asScala.map(toScala).toMap 
  case m => m 
} 

Oder:

private def toScalaOption(v: Any): Any = vmatch { 
  case null => None 
  case m: java.util.Map[_, _] => m.asScala.mapValues(toScala).toMap 
  case m: java.util.List[_] => m.asScala.map(toScala).toMap 
  case m: java.util.Set[_] => m.asScala.map(toScala).toMap 
  case m => Some(m) 
} 

Prost

+0

Ich mache gerade so etwas Joan, aber ich würde gerne Überladung verwenden, ist es möglich. – bugs

+1

Nicht möglich: Überladen wird vollständig zur Kompilierzeit basierend auf den statischen Typen der Argumente aufgelöst. Wenn also die Map-Werte vom Typ 'Any' sind, müssen Sie die möglichen Werttypen zur Laufzeit unterscheiden (wie Joan es hier tut)). –