В scala.collection
, есть два очень похожих объекта JavaConversions
и JavaConverters
.
- В чем разница между этими двумя объектами?
- Почему они оба существуют?
- Когда я хочу использовать один против другого?
В scala.collection
, есть два очень похожих объекта JavaConversions
и JavaConverters
.
Ответы:
РЕДАКТИРОВАТЬ: 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-коллекции в связанную Scala-коллекцию.
Вы можете использовать его с import collection.JavaConversions._
. При необходимости компилятор автоматически преобразует коллекцию java в правильный тип scala.
JavaConverters
набор декораторов, который помогает преобразовывать коллекции java или scala в коллекции scala или java, используя методы asScala
или asJava
методы, которые будут неявно добавлены в коллекцию, которую вы хотите преобразовать. Чтобы использовать эти конвертеры, вам необходимо импортировать:
import collection.JavaConverters._
Вы должны предпочесть, так JavaConversions
как это обычно проще в использовании (не нужно использовать asScala
или asJava
).