web-dev-qa-db-fra.com

Convertir une carte Java en carte Scala

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.

38
Ha11owed

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))
59
gourlaysama

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());

Basé sur: https://stackoverflow.com/a/45373345/5209935

1
Matthew

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.

0
AJ.P

Carte immuable myJavaMap.asScala.toMap

Carte modifiable myJavaMap.asScala

0
Manali Bhosale