Яка різниця між JavaConverters та JavaConversions у Scala?


Відповіді:


253

EDIT: Java Conversionsпотрапив @deprecatedу Scala 2.13.0. Замість цього використовуйте scala.jdk.CollectionConverters .

JavaConversionsнадають низку неявних методів, які перетворюють між колекцією Java та найближчою відповідною колекцією Scala, і навпаки. Це робиться шляхом створення обгортки, яка реалізує або інтерфейс Scala, і перенаправляє дзвінки до базової колекції Java, або інтерфейс Java, перенаправляючи дзвінки до основної колекції Scala.

JavaConvertersвикористовує шаблон pimp-my-library для "додавання" asScalaметоду до колекцій Java, а asJavaметод до колекцій Scala, який повертає відповідні обгортки, обговорені вище. Він новіший (починаючи з версії 2.8.1), ніж JavaConversions(з 2.8) і робить перетворення між колекцією Scala та Java явним. Всупереч тому, що Девід пише у своїй відповіді, я б рекомендував вам зробити це звичним для використання, JavaConvertersоскільки ви будете набагато рідше писати код, який робить багато неявних перетворень, оскільки ви можете контролювати єдине місце, де це станеться : де ви пишете .asScalaабо .asJava.

Ось методи перетворення, які JavaConvertersзабезпечують:

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]

Однак для використання конверсій безпосередньо з Java вам краще скористатися методами JavaConversionsпрямого виклику ; наприклад:

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
Так, використовуйте JavaConverters над JavaConversions ,. Але також подумайте про використання github.com/scalaj/scalaj-collection, оскільки це має деякі переваги, як перетворення java.util.List у Seq. (Чи є вищевказаний список з 2.8.1?)
олюї

7
@David Хоча неявні конверсії на кшталт тих, що надаються JavaConversionsзручними, ви можете швидко пропустити всі місця, де їх може вставити компілятор. Ви керуєте цими місцями за допомогою JavaConverters. Це вся дискусія про неявну та явну конверсію.
Жан-Філіп Пеллет

1
@ Жан-Філіппеллет неявні перетворення в Scala базуються на обсягах, тому, якщо цього не зробити import JavaConversions._, конверсії не відбудуться, щоб ви мали контроль над тим, що перетворюється. Якщо ви імпортуєте правильний шлях (лише за потреби), ви маєте повний контроль над тим, де здійснюється перетворення.
Девід

2
@David… і у JavaConvertersвас є додаткова безпека, що нічого не відбувається, якщо ви не пишете це явно. Це додаткова безпека, і це, мабуть, саме тому цей клас додали.
Жан-Філіп Пеллет

23
Ви можете подумати, що найменування буде краще: наприклад, щось на кшталт "JavaConversionsImplicit" та "JavaConversionsExplicit" було б простіше розрізнити.
Раман

52

Для всіх, хто зайнявся цим питанням, починаючи з Scala 2.12.x, JavaConversionsтепер застарілий і JavaConvertersє кращим методом.


2
Оскільки Scala 2.13, JavaConvertersзастаріла, і scala.jdk.CollectionConvertersє кращим методом;)
антонон

4

В Scala 2.13, JavaConvertersбули застарілими на користь scala.jdk.CollectionConverters:

... новий пакет scala.jdkз об'єктами CollectionConverters (класичні колекції Java, подібні до collection.JavaConverters2.12) StreamConverters, FunctionConvertersта OptionConverters...


3

Як пояснено в API, JavaConversionsце набір неявних перетворень, який перетворює колекції java в пов'язану колекцію шкал.

Ви можете використовувати його з import collection.JavaConversions._. У разі необхідності компілятор автоматично перетворить колекцію java у правильний тип scala.

JavaConvertersявляють собою набір декоратора , який допомагає перетворити Java або SCALA колекції SCALA або ява колекцій з використанням asScalaабо asJavaметодів , які будуть неявно додані в колекцію , яку ви хочете перетворити. Для використання цих перетворювачів вам потрібно імпортувати:

import collection.JavaConverters._

Вам слід віддати перевагу, JavaConversionsоскільки це звичайно простіше у використанні (не потрібно використовувати asScalaабо asJava).


15
Хоча використовувати абсолютно неявний підхід JavaConverters простіше написати, важче читати. Сучасний стиль Scala дозволяє припустити, що краще чітко викликати методи для здійснення перетворень, саме тому зараз переважні JavaConverters.
Лейф Вікленд

У програмі Scala 2.12 застарілі JavaConversions
Анджей Васовський
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.