Conversion d'une collection Java en collection Scala


87

Lié à la question Stack Overflow, équivalent Scala du nouveau HashSet (Collection) , comment convertir une collection Java (par java.util.Listexemple) en une collection Scala List?

J'essaie en fait de convertir un appel d'API Java en Spring SimpleJdbcTemplate , qui renvoie a java.util.List<T>, en un Scala immuable HashSet. Donc par exemple:

val l: java.util.List[String] = javaApi.query( ... )
val s: HashSet[String] = //make a set from l

Cela semble fonctionner. La critique est la bienvenue!

import scala.collection.immutable.Set
import scala.collection.jcl.Buffer 
val s: scala.collection.Set[String] =
                      Set(Buffer(javaApi.query( ... ) ) : _ *)

Réponses:


17

Votre dernière suggestion fonctionne, mais vous pouvez également éviter d'utiliser jcl.Buffer:

Set(javaApi.query(...).toArray: _*)

Notez qu'il scala.collection.immutable.Setest rendu disponible par défaut grâce à Predef.scala.


9
Cette suggestion ne fonctionne pas là où je veux conserver les informations de type
oxbow_lakes

126

Pour référence future: Avec Scala 2.8, cela pourrait être fait comme ceci:

import scala.collection.JavaConversions._
val list = new java.util.ArrayList[String]()
list.add("test")
val set = list.toSet

setest un scala.collection.immutable.Set[String]après ça.

Voir également la réponse de Ben James pour une manière plus explicite (en utilisant JavaConverters), qui semble être recommandée maintenant.


On dirait que maintenant JavaConversionsa des implicites rendant l' toSetappel non nécessaire.
Rajish

@Rajish Je pense que c'est mieux si la conversion est explicite (voir stackoverflow.com/questions/8301947/… )
krookedking

vous avez raison, il vaut mieux utiliser import scala.collection.JavaConverters._
Abhishek Sengupta

62

Si vous voulez être plus explicite que les JavaConversions démontrées dans la réponse de robinst , vous pouvez utiliser JavaConverters:

import scala.collection.JavaConverters._
val l = new java.util.ArrayList[java.lang.String]
val s = l.asScala.toSet

25

JavaConversions ( réponse de robinst ) et JavaConverters ( réponse de Ben James ) sont obsolètes avec Scala 2.10 .

Au lieu de JavaConversions, utilisez:

import scala.collection.convert.wrapAll._

comme suggéré par aleksandr_hramcov .

Au lieu de JavaConverters, utilisez:

import scala.collection.convert.decorateAll._

Pour les deux, il est également possible d'importer uniquement les conversions / convertisseurs vers Java ou Scala respectivement, par exemple:

import scala.collection.convert.wrapAsScala._

Mise à jour: La déclaration ci-dessus selon laquelle JavaConversions et JavaConverters étaient obsolètes semble être fausse. Il y avait des propriétés obsolètes dans Scala 2.10, ce qui entraînait des avertissements d'obsolescence lors de leur importation. Les importations alternatives ici semblent donc être uniquement des alias. Bien que je les préfère toujours, comme à mon humble avis, les noms sont plus appropriés.


Pourquoi dites-vous que les JavaConversions et les JavaConverters sont obsolètes? Dans la documentation actuelle 2.11.8, les deux ne sont pas marqués comme étant obsolètes et ils n'ont pas non plus de référence à 'decorateAll' ou 'wrapAll' indiquant que c'est l'usage nouveau et préféré.
Joost den Boer

@JoostdenBoer Semble il y avait quelques décorateurs dépréciées il à Scala 2.10, mais ils semblent avoir été enlevés à nouveau avec Scala 2,11.
stempler

14

Vous pouvez également explorer cette excellente bibliothèque: scalaj-collection qui a une conversion bidirectionnelle entre les collections Java et Scala. Dans votre cas, pour convertir une java.util.List en liste Scala, vous pouvez le faire:

val list = new java.util.ArrayList[java.lang.String]
list.add("A")
list.add("B")
list.asScala

1
Cette bibliothèque est la meilleure chose qui soit. Fonctionne vraiment très bien.
Michael Neale

6
Revisitant ceci après quelques années, les JavaConverters de Scala sont la voie à suivre.
Surya Suravarapu

4

À partir de Scala 2.13, le package scala.jdk.CollectionConvertersremplace les packages scala.collection.JavaConverters/JavaConversions._:

import scala.jdk.CollectionConverters._

// val javaList: java.util.List[String] = java.util.Arrays.asList("one","two","three")
javaList.asScala
// collection.mutable.Buffer[String] = Buffer("one", "two", "three")
javaList.asScala.toSet
// collection.immutable.Set[String] = Set("one", "two", "three")

3
val array = java.util.Arrays.asList("one","two","three").toArray

val list = array.toList.map(_.asInstanceOf[String])

c'est une excellente réponse et a résolu mon problème. La plupart des méthodes mentionnées sur Internet convertissent simplement (par exemple) java.util.List [java.lang.Long] en scala.collection.immutable.List [java.lang.Long]. Donc, cette méthode a fonctionné pour moi pour le convertir en scala.collection.immutable.List [scala.Long]
ajkl

2

Vous pouvez ajouter les informations de type dans l'appel toArray pour que l'ensemble soit paramétré:

 val s = Set(javaApi.query(....).toArray(new Array[String](0)) : _*)

Cela peut être préférable car le package de collections subit une refonte majeure pour Scala 2.8 et le package scala.collection.jcl disparaît


1

Vous pouvez convertir la collection Java en un tableau, puis créer une liste Scala à partir de cela:

val array = java.util.Arrays.asList("one","two","three").toArray
val list = List.fromArray(array)

2
Ce n'est pas génial parce que mon java.util.List revient d'une API Java sous forme de liste paramétrée (donc mon appel à l'API donne un java.util.List <String>) - J'essaye de tourner ceci into a scala immutable HashSet
oxbow_lakes

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.