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