В scala.collection
, є два дуже схожі об'єкти JavaConversions
і JavaConverters
.
- Яка різниця між цими двома об’єктами?
- Чому вони обидва існують?
- Коли я хочу використовувати один проти іншого?
В scala.collection
, є два дуже схожі об'єкти JavaConversions
і JavaConverters
.
Відповіді:
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
JavaConversions
зручними, ви можете швидко пропустити всі місця, де їх може вставити компілятор. Ви керуєте цими місцями за допомогою JavaConverters
. Це вся дискусія про неявну та явну конверсію.
import JavaConversions._
, конверсії не відбудуться, щоб ви мали контроль над тим, що перетворюється. Якщо ви імпортуєте правильний шлях (лише за потреби), ви маєте повний контроль над тим, де здійснюється перетворення.
JavaConverters
вас є додаткова безпека, що нічого не відбувається, якщо ви не пишете це явно. Це додаткова безпека, і це, мабуть, саме тому цей клас додали.
Для всіх, хто зайнявся цим питанням, починаючи з Scala 2.12.x, JavaConversions
тепер застарілий і JavaConverters
є кращим методом.
JavaConverters
застаріла, і scala.jdk.CollectionConverters
є кращим методом;)
В Scala 2.13, JavaConverters
були застарілими на користь scala.jdk.CollectionConverters
:
... новий пакет
scala.jdk
з об'єктамиCollectionConverters
(класичні колекції Java, подібні доcollection.JavaConverters
2.12)StreamConverters
,FunctionConverters
таOptionConverters
...
Як пояснено в API, JavaConversions
це набір неявних перетворень, який перетворює колекції java в пов'язану колекцію шкал.
Ви можете використовувати його з import collection.JavaConversions._
. У разі необхідності компілятор автоматично перетворить колекцію java у правильний тип scala.
JavaConverters
являють собою набір декоратора , який допомагає перетворити Java або SCALA колекції SCALA або ява колекцій з використанням asScala
або asJava
методів , які будуть неявно додані в колекцію , яку ви хочете перетворити. Для використання цих перетворювачів вам потрібно імпортувати:
import collection.JavaConverters._
Вам слід віддати перевагу, JavaConversions
оскільки це звичайно простіше у використанні (не потрібно використовувати asScala
або asJava
).