Reputation: 1563
I'm working on mixed Java-Scala projects, and quite often I need to convert collections.
When I want to convert a collection of primitives, I should be writing something like this
val coll: Seq[Int] = Seq(1, 2, 3)
import scala.collection.JavaConverters._
val jColl = coll.map(v => Int.box(v)).asJava
However, I know that with both Java and Scala generic collections use boxed values, so I can safely avoid iterating with needless boxing and just write
val jColl = coll.asJava.asInstanceOf[java.util.List[java.lang.Integer]]
However, compiler won't complain if I'll make a mistake in either collection type or element type.
Is there a type-safe way of doing this avoiding extra iteration? Is there at least a way to keep checks for collection type?
Upvotes: 1
Views: 300
Reputation: 18424
Well, I can't think of a way to avoid the scala.Int
-> java.lang.Integer
conversion being a bit manual or unsafe, but if you only implement it once and reuse it, it can pretty much eliminate the risk.
One approach might be:
import scala.language.higherKinds
implicit class IntCollectionBoxer[C[_] <: java.lang.Iterable[_]](elems: C[Int]) {
def asJavaBoxed: C[java.lang.Integer] = elems.asInstanceOf[C[java.lang.Integer]]
}
(repeat for Double and other types)
Then usage would be this, which is pretty hard to make a mistake with:
val jColl = coll.asJava.asJavaBoxed
You might wish to change the bound on C
depending on your usage as well.
Upvotes: 1