What is the difference between JavaConverters and JavaConversions in Scala?
In Scala 2.13, JavaConverters
have been deprecated in favour of scala.jdk.CollectionConverters
:
...new package
scala.jdk
with objectsCollectionConverters
(classic Java collections, similar tocollection.JavaConverters
in 2.12),StreamConverters
,FunctionConverters
andOptionConverters
...
For anyone landing on this question since Scala 2.12.x, JavaConversions
is now deprecated and JavaConverters
is the preferred method.
EDIT: Java Conversions
got @deprecated
in Scala 2.13.0. Use scala.jdk.CollectionConverters instead.
JavaConversions
provide a series of implicit methods that convert between a Java collection and the closest corresponding Scala collection, and vice versa. This is done by creating wrappers that implement either the Scala interface and forward the calls to the underlying Java collection, or the Java interface, forwarding the calls to the underlying Scala collection.
JavaConverters
uses the pimp-my-library pattern to “add” the asScala
method to the Java collections and the asJava
method to the Scala collections, which return the appropriate wrappers discussed above. It is newer (since version 2.8.1) than JavaConversions
(since 2.8) and makes the conversion between Scala and Java collection explicit. Contrary to what David writes in his answer, I'd recommend you make it a habit to use JavaConverters
as you'll be much less likely to write code that makes a lot of implicit conversions, as you can control the only spot where that will happen: where you write .asScala
or .asJava
.
Here's the conversion methods that JavaConverters
provide:
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]
To use the conversions directly from Java, though, you're better off calling methods from JavaConversions
directly; e.g.:
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