Scala勉強会のときに、誰かから、ScalaのコレクションをJavaのコレクションに変換するためのライブラリって無いの?という質問があって、それに対して、そういうものは無いけど、割とすぐ書けますよ、てな感じで答えたのをふと思い出して、サクっと書いてみた(Scala-sandboxにも既に同様のコードを置いてあるけど、ちょっと違う)。
package example import java.util object ToJavaCollection { class ToJavaListOrSet[A](it :Iterable[A]){ def toJavaList :util.List[A] = { it.foldLeft(new util.ArrayList[A]){(list, e) => list.add(e); list} } def toJavaSet :util.Set[A] = { it.foldLeft(new util.HashSet[A]){(set, e) => set.add(e); set} } } class ToJavaMap[A, B](it :Iterable[(A, B)]) { def toJavaMap :util.Map[A, B] = { it.foldLeft(new util.HashMap[A, B]){(map, e) => map.put(e._1, e._2); map } } } implicit def toJavaListOrSet[A](it :Iterable[A]) = new ToJavaListOrSet[A](it) implicit def toJavaMap[A, B](it :Iterable[(A, B)]) = new ToJavaMap[A, B](it) }
使う側のコードはこんな感じ。
import example.ToJavaCollection._ val javaList = List(1, 2, 3).toJavaList val javaSet = Set(1, 2, 3).toJavaSet val javaMap = Map("A" -> 1, "B" -> 2, "C" -> 3).toJavaMap println(javaList + ":" + javaList.getClass) println(javaSet + ":" + javaSet.getClass) println(javaMap + ":" + javaMap.getClass)
実行結果:
[1, 2, 3]:class java.util.ArrayList [1, 2, 3]:class java.util.HashSet {A=1, B=2, C=3}:class java.util.HashMap
これだと、変換元のScalaのコレクションの要素数が多い場合、コピーのコストが高くつく可能性があるが、それが問題になる場合は、scala.collection.jclパッケージの逆アプローチで、ScalaのコレクションをJavaのコレクションに見せかけるラッパーがあると良いかも。