Quelle est la différence entre JavaConverters et JavaConversions dans Scala?

Réponses:

253

EDIT: Java Conversionsentré @deprecateddans Scala 2.13.0. Utilisez plutôt scala.jdk.CollectionConverters .

JavaConversionsfournir une série de méthodes implicites qui convertissent entre une collection Java et la collection Scala correspondante la plus proche, et vice versa. Pour ce faire, créez des wrappers qui implémentent soit l'interface Scala et transfèrent les appels vers la collection Java sous-jacente, soit l'interface Java, en transférant les appels vers la collection Scala sous-jacente.

JavaConvertersutilise le modèle pimp-my-library pour «ajouter» la asScalaméthode aux collections Java et la asJavaméthode aux collections Scala, qui renvoient les wrappers appropriés décrits ci-dessus. Il est plus récent (depuis la version 2.8.1) que JavaConversions(depuis la 2.8) et rend explicite la conversion entre Scala et la collection Java. Contrairement à ce que David écrit dans sa réponse, je vous recommande de prendre l'habitude d'utiliser JavaConverterscar vous serez beaucoup moins susceptible d'écrire du code qui fait beaucoup de conversions implicites, car vous pouvez contrôler le seul endroit où cela se produira. : où vous écrivez .asScalaou .asJava.

Voici les méthodes de conversion qui JavaConvertersfournissent:

Pimped Type                            | Conversion Method   | Returned Type
=================================================================================================
scala.collection.Iterator              | asJava              | java.util.Iterator
scala.collection.Iterator              | asJavaEnumeration   | java.util.Enumeration
scala.collection.Iterable              | asJava              | java.lang.Iterable
scala.collection.Iterable              | asJavaCollection    | java.util.Collection
scala.collection.mutable.Buffer        | asJava              | java.util.List
scala.collection.mutable.Seq           | asJava              | java.util.List
scala.collection.Seq                   | asJava              | java.util.List
scala.collection.mutable.Set           | asJava              | java.util.Set
scala.collection.Set                   | asJava              | java.util.Set
scala.collection.mutable.Map           | asJava              | java.util.Map
scala.collection.Map                   | asJava              | java.util.Map
scala.collection.mutable.Map           | asJavaDictionary    | java.util.Dictionary
scala.collection.mutable.ConcurrentMap | asJavaConcurrentMap | java.util.concurrent.ConcurrentMap
—————————————————————————————————————————————————————————————————————————————————————————————————
java.util.Iterator                     | asScala             | scala.collection.Iterator
java.util.Enumeration                  | asScala             | scala.collection.Iterator
java.lang.Iterable                     | asScala             | scala.collection.Iterable
java.util.Collection                   | asScala             | scala.collection.Iterable
java.util.List                         | asScala             | scala.collection.mutable.Buffer
java.util.Set                          | asScala             | scala.collection.mutable.Set
java.util.Map                          | asScala             | scala.collection.mutable.Map
java.util.concurrent.ConcurrentMap     | asScala             | scala.collection.mutable.ConcurrentMap
java.util.Dictionary                   | asScala             | scala.collection.mutable.Map
java.util.Properties                   | asScala             | scala.collection.mutable.Map[String, String]

Cependant, pour utiliser les conversions directement à partir de Java, il vaut mieux appeler JavaConversionsdirectement les méthodes ; par exemple:

List<String> javaList = new ArrayList<String>(Arrays.asList("a", "b", "c"));
System.out.println(javaList); // [a, b, c]
Buffer<String> scalaBuffer = JavaConversions.asScalaBuffer(javaList);
System.out.println(scalaBuffer); // Buffer(a, b, c)
List<String> javaListAgain = JavaConversions.bufferAsJavaList(scalaBuffer);
System.out.println(javaList == javaListAgain); // true
Jean-Philippe Pellet
la source
5
Oui, utilisez JavaConverters sur JavaConversions. Mais envisagez également d'utiliser github.com/scalaj/scalaj-collection car cela présente certains avantages comme la conversion de java.util.List en Seq. (La liste ci-dessus est-elle de 2.8.1?)
oluies
7
@David Bien que les conversions implicites comme celles fournies par JavaConversionssoient pratiques, vous pouvez rapidement ignorer tous les endroits où elles peuvent être insérées par le compilateur. Vous contrôlez ces endroits avec JavaConverters. C'est toute la discussion sur la conversion implicite vs explicite.
Jean-Philippe Pellet
1
@ Les conversions implicites Jean-PhilippePellet dans Scala sont basées sur la portée, donc si vous ne le faites pas import JavaConversions._, les conversions ne se produiront pas, vous avez donc le contrôle sur ce qui est converti. Si vous placez l'importation dans le bon sens (uniquement lorsque cela est nécessaire), vous avez un contrôle total sur l'endroit où la conversion est effectuée.
David
2
@David… et JavaConvertersvous avez la sécurité supplémentaire que rien ne se passe à moins que vous ne l' écriviez explicitement. C'est une sécurité supplémentaire, et c'est probablement pourquoi cette classe a été ajoutée.
Jean-Philippe Pellet
23
On pourrait penser que la dénomination serait meilleure: par exemple, quelque chose comme "JavaConversionsImplicit" et "JavaConversionsExplicit" aurait été plus facile à distinguer.
Raman
52

Pour quiconque atterrit sur cette question depuis Scala 2.12.x, JavaConversionsest désormais obsolète et JavaConvertersest la méthode préférée.

Ryan Burke
la source
2
Depuis Scala 2.13, JavaConvertersest obsolète et scala.jdk.CollectionConvertersest la méthode préférée;)
antonone
4

Dans Scala 2.13, JavaConvertersont été dépréciés au profit de scala.jdk.CollectionConverters:

... nouveau package scala.jdkavec des objets CollectionConverters (collections Java classiques, similaires à collection.JavaConverters2.12) StreamConverters, FunctionConverterset OptionConverters...

Mario Galic
la source
3

Comme expliqué dans l'API, JavaConversionsest un ensemble de conversions implicites qui transforme les collections java en collection scala associée.

Vous pouvez l'utiliser avec un import collection.JavaConversions._. Si nécessaire, le compilateur transformera automatiquement la collection java en le bon type de scala.

JavaConverterssont un ensemble de décorateur qui aide à transformer les collections java ou scala en collections scala ou java en utilisant des méthodes asScalaou asJavaqui seront implicitement ajoutées à la collection que vous souhaitez transformer. Pour utiliser ces convertisseurs, vous devez importer:

import collection.JavaConverters._

Vous devriez préférer JavaConversionscar il est généralement plus facile à utiliser (pas besoin d'utiliser asScalaou asJava).

David
la source
15
Bien que l'utilisation de l'approche totalement implicite de JavaConverters soit plus facile à écrire, elle est plus difficile à lire. Le style Scala actuel suggère qu'il est préférable d'appeler explicitement des méthodes pour effectuer des conversions, c'est pourquoi les convertisseurs Java sont désormais préférés.
Leif Wickland
JavaConversions est déconseillé dans Scala 2.12
Andrzej Wąsowski