Konstantin Pelepelin
Konstantin Pelepelin

Reputation: 1563

Safe cast of Scala collection containing primitives

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

Answers (1)

Joe K
Joe K

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

Related Questions