Qual è la differenza tra JavaConverters e JavaConversions in Scala?


Risposte:


253

EDIT: Java Conversionsottenuto @deprecatedin Scala 2.13.0. Utilizzare invece scala.jdk.CollectionConverters .

JavaConversionsfornire una serie di metodi impliciti che convertono tra una raccolta Java e la raccolta Scala corrispondente più vicina e viceversa. Questo viene fatto creando involucri che implementano l'interfaccia Scala e inoltrano le chiamate alla raccolta Java sottostante o l'interfaccia Java, inoltrando le chiamate alla raccolta Scala sottostante.

JavaConvertersusa il modello pimp-my-library per "aggiungere" il asScalametodo alle raccolte Java e il asJavametodo alle raccolte Scala, che restituiscono i wrapper appropriati discussi sopra. È più recente (dalla versione 2.8.1) rispetto a JavaConversions(dalla 2.8) e rende esplicita la conversione tra la raccolta Scala e Java. Contrariamente a quanto scrive David nella sua risposta, ti consiglio di prendere l'abitudine di usarlo JavaConverterspoiché avrai molte meno probabilità di scrivere codice che crea molte conversioni implicite, in quanto puoi controllare l'unico punto in cui ciò accadrà : dove scrivi .asScalao .asJava.

Ecco i metodi di conversione che JavaConvertersforniscono:

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]

Per utilizzare le conversioni direttamente da Java, tuttavia, è meglio chiamare JavaConversionsdirettamente i metodi ; per esempio:

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

5
Sì, utilizzare JavaConverters su JavaConversions. Ma considera anche l'uso di github.com/scalaj/scalaj-collection in quanto ha alcuni vantaggi nella conversione di java.util.List in Seq. (La lista precedente è dalla 2.8.1?)
oluies,

7
@David Sebbene le conversioni implicite come quelle fornite da JavaConversionssiano utili, potresti trascurare rapidamente tutti i luoghi in cui possono essere inserite dal compilatore. Tu controlli quei posti con JavaConverters. È l'intera discussione sulla conversione implicita vs esplicita.
Jean-Philippe Pellet,

1
@ Jean-PhilippePellet le conversioni implicite in Scala sono basate su Scope, quindi se non lo fai import JavaConversions._, le conversioni non si verificheranno in modo da avere il controllo su ciò che viene convertito. Se si posiziona l'importazione nel modo giusto (solo quando necessario), si ha il pieno controllo su dove viene eseguita la conversione.
David

2
@David… e con JavaConverterste hai la sicurezza aggiuntiva che non succede nulla se non lo scrivi esplicitamente. Questa è una sicurezza aggiuntiva ed è probabilmente il motivo per cui questa classe è stata aggiunta.
Jean-Philippe Pellet,

23
Penseresti che la denominazione sarebbe migliore: ad esempio qualcosa come "JavaConversionsImplicit" e "JavaConversionsExplicit" sarebbe stato più facile da distinguere.
Raman,

52

Per chiunque atterri su questa domanda a partire da Scala 2.12.x, JavaConversionsè ora obsoleto ed JavaConvertersè il metodo preferito.


2
Dal momento che Scala 2.13, JavaConvertersè deprecato, ed scala.jdk.CollectionConvertersè il metodo preferito;)
antonone

4

In Scala 2.13, JavaConverterssono stati deprecati a favore di scala.jdk.CollectionConverters:

... nuovo pacchetto scala.jdkcon oggetti CollectionConverters (raccolte Java classiche, simili a collection.JavaConvertersin 2.12) StreamConverters, FunctionConverterse OptionConverters...


3

Come spiegato nell'API, JavaConversionsè un insieme di conversioni implicite che trasforma le raccolte java in raccolte scala correlate.

Puoi usarlo con un import collection.JavaConversions._. Se necessario, il compilatore trasformerà automaticamente la raccolta java nel giusto tipo di scala.

JavaConverterssono un insieme di decoratrice che aiuta a trasformare le collezioni di Java o Scala a collezioni Scala o Java che utilizzano asScalao asJavametodi che saranno implicitamente aggiunti alla collezione che si desidera trasformare. Per utilizzare questi convertitori, è necessario importare:

import collection.JavaConverters._

Dovresti preferire in JavaConversionsquanto è generalmente più facile da usare (non è necessario utilizzare asScalao asJava).


15
Sebbene l'utilizzo dell'approccio totalmente implicito di JavaConverters sia più facile da scrivere, è più difficile da leggere. L'attuale stile Scala suggerisce che è meglio chiamare esplicitamente i metodi per eseguire le conversioni, motivo per cui i JavaConverter sono ora preferiti.
Leif Wickland,

JavaConversions è deprecato in Scala 2.12
Andrzej Wąsowski
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.