9

Looking at the code in JavaConversions and JavaConverters, I am unsure which the "correct" way (with 2.10) to convert between Java and Scala collections (in either direction) is.

There seem to be lots of @deprecated annotations.

Has a definitive answer from the Scala Team (Typesafe?) been published?

Thanks, John

John Smith
  • 3,037
  • 5
  • 29
  • 31
  • See http://stackoverflow.com/questions/8301947/what-is-the-difference-between-javaconverters-and-javaconversions-in-scala – jond3k Jul 26 '12 at 22:57

3 Answers3

16

This is the poster child example for the dangers of import JavaConversions._:

scala> val m = Map(1 -> "one")
m: scala.collection.immutable.Map[Int,String] = Map(1 -> one)

scala> m.contains(1)
res0: Boolean = true

scala> m.contains("")
<console>:9: error: type mismatch;
 found   : String("")
 required: Int
              m.contains("")
                         ^

scala> import collection.JavaConversions._
import collection.JavaConversions._

scala> m.contains("")
res2: Boolean = false

Instead of issuing a type error, the compiler converts the Scala Map to to a java.util.Map, which has a looser signature that accepts Object.

retronym
  • 54,768
  • 12
  • 155
  • 168
13

I don't know of any such proclamation, but you should just always use JavaConverters, i.e. the ones that require you to indicate conversions with .asScala and .asJava.

As I understand it, JavaConverters were brought in in 2.8.1 because the JavaConversions in 2.8 were dangerous and made it easy to accidentally convert things where you weren't expecting it.

Luigi Plinge
  • 50,650
  • 20
  • 113
  • 180
6

The two works in a different way:

  • With JavaConverters your objects will be pimped into a class which support asScala and asJava, which let you programmatically convert your collection.

  • With JavaConversions, a Java/Scala collection will be automatically converted when required

The risk with the latter is to obtain wrong or unnecessary conversions paying a performance fault. Additionally, at least in Scala 2.9 there is no caching of implicit conversion, i.e. if the same conversion is applied twice inside a method, the conversion code is called twice.

When you explicitely convert a collection, if you need it in the "Java" version, you will avoid to call twice .asScala in the same method.

Edmondo
  • 19,559
  • 13
  • 62
  • 115