J'ai une carte Java: Java.util.Map<SomeObject, Java.util.Collection<OtherObject>>
.__ et j'aimerais la convertir en carte scala: Map[SomeObject, Set[OtherObject]]
J'ai utilisé mapAsScalaMap mais le résultat n'est pas tout à fait ce que je veux, le résultat est: Map[SomeObject, Java.util.Collection[OtherObject]]
. Comment puis-je résoudre ce problème pour convertir également la collection en un ensemble?
NOTE: En fait, mon problème initial était de convertir le ArrayListMultimap<SomeObject, OtherObject>
de Google en un MultiMap[SomeObject, OtherObject]
, mais comme ce n'était pas possible, j'ai divisé le problème. Si vous avez une solution au problème initial, je l'accepterai également comme solution.
Edit : la méthode recommandée consiste maintenant à utiliser JavaConverters
et la méthode .asScala
:
import scala.collection.JavaConverters._
val myScalaMap = myJavaMap.asScala.mapValues(_.asScala.toSet)
Cela présente l'avantage de ne pas utiliser de conversions implicites magiques mais d'appels explicites à .asScala
, tout en restant clair et cohérent.
La réponse originale avec JavaConversions
:
Vous pouvez utiliser scala.collection.JavaConversions
pour convertir implicitement entre Java et Scala:
import scala.collection.JavaConversions._
val myScalaMap = myJavaMap.mapValues(_.toSet)
L'appel de mapValues
déclenchera une conversion implicite de Java Map
en une scala Map
, puis de l'appel de toSet
sur la collection Java avec une conversion implicite de celle-ci en scala, puis en Set
.
Par défaut, il retourne une variable Map
mutable. Vous pouvez en obtenir une non modifiable avec un .toMap
supplémentaire.
Exemple court:
scala> val a: Java.util.Map[String, Java.util.Collection[String]] = new Java.util.HashMap[String, Java.util.Collection[String]]
a: Java.util.Map[String,Java.util.Collection[String]] = {}
scala> val b = new Java.util.ArrayList[String]
b: Java.util.ArrayList[String] = []
scala> b.add("hi")
res5: Boolean = true
scala> a.put("a", b)
res6: Java.util.Collection[String] = []
scala> import scala.collection.JavaConversions._
import scala.collection.JavaConversions._
scala> val c = a.mapValues(_.toSet)
c: scala.collection.Map[String,scala.collection.immutable.Set[String]] = Map(a -> Set(hi))
scala> c.toMap
res7: scala.collection.immutable.Map[String,scala.collection.immutable.Set[String]] = Map(a -> Set(hi))
Si vous devez le faire depuis Java:
List<Tuple2<A, B>> tuples = javaMap.entrySet().stream()
.map(e -> Tuple2.apply(e.getKey(), e.getValue()))
.collect(Collectors.toList());
scala.collection.Map scalaMap = scala.collection.Map$.MODULE$.apply(JavaConversions.asScalaBuffer(tuples).toSeq());
Vous pouvez convertir la carte Java en carte Scala en utilisant la fonction ci-dessous:
val scalaMap = javaMap.asScala;
Pour utiliser cela, vous devez importer la bibliothèque d'importation scala.collection.JavaConverters._.
J'espère que cela t'aides.
Carte immuable myJavaMap.asScala.toMap
Carte modifiable myJavaMap.asScala