134

How to convert Scala's scala.List into Java's java.util.List?

Xavier Guihot
  • 54,987
  • 21
  • 291
  • 190
Alex Baranosky
  • 48,865
  • 44
  • 102
  • 150

9 Answers9

184

Not sure why this hasn't been mentioned before but I think the most intuitive way is to invoke the asJava decorator method of JavaConverters directly on the Scala list:

scala> val scalaList = List(1,2,3)
scalaList: List[Int] = List(1, 2, 3)

scala> import scala.collection.JavaConverters._
import scala.collection.JavaConverters._

scala> scalaList.asJava
res11: java.util.List[Int] = [1, 2, 3]
dimitrisli
  • 20,895
  • 12
  • 59
  • 63
  • 6
    It also requires you to be explicit rather than depend on some implicit magic that might be unwanted some time. – Kamil Lelonek Nov 28 '14 at 11:56
  • This causes problems if serialising the list for subsequent use in Java code... it results in ClassNotFoundException: scala.collection.convert.Wrappers. Arrays.asList(foo : _*) works in this case. – Mohan Jun 27 '15 at 11:41
  • I come to this page every time I need to use Java in Scala. Unfortunately there is no way idea suggest me proper import suggestion for ".asJava" (( – mulya Sep 13 '19 at 09:20
70

Scala List and Java List are two different beasts, because the former is immutable and the latter is mutable. So, to get from one to another, you first have to convert the Scala List into a mutable collection.

On Scala 2.7:

import scala.collection.jcl.Conversions.unconvertList
import scala.collection.jcl.ArrayList
unconvertList(new ArrayList ++ List(1,2,3))

From Scala 2.8 onwards:

import scala.collection.JavaConversions._
import scala.collection.mutable.ListBuffer
asList(ListBuffer(List(1,2,3): _*))
val x: java.util.List[Int] = ListBuffer(List(1,2,3): _*)

However, asList in that example is not necessary if the type expected is a Java List, as the conversion is implicit, as demonstrated by the last line.

Jacek Laskowski
  • 72,696
  • 27
  • 242
  • 420
Daniel C. Sobral
  • 295,120
  • 86
  • 501
  • 681
  • The val x: java.util.List[Int] is still immutable. Just try in Java to x.add(something) -- it will throw error – Vitamon May 08 '13 at 12:48
  • 1
    @Vitamon It doesn't throw any error for me -- I just tested it to confirm. – Daniel C. Sobral May 08 '13 at 16:46
  • 4
    Deprecated in favour of `scala.collection.JavaConverters` from 2.12 on – Jeroen Kransen Feb 04 '19 at 13:54
  • for 2.12.1, when immediately iterating over the Java List with a Scala for loop, I've had better luck with asScalaBuffer() in the JavaConverters package: https://www.scala-lang.org/api/2.12.1/scala/collection/JavaConverters$.html – Sarah Messer Sep 04 '19 at 13:43
26

To sum up the previous answers

Assuming we have the following List:

scala> val scalaList = List(1,2,3)
scalaList: List[Int] = List(1, 2, 3)

If you want to be explicit and tell exactly what you want to convert:

scala> import scala.collection.JavaConverters._
import scala.collection.JavaConverters._

scala> scalaList.asJava
res11: java.util.List[Int] = [1, 2, 3]

If you don't want co control conversions and let compiler make implicit work for you:

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

scala> val javaList: java.util.List[Int] = scalaList
javaList: java.util.List[Int] = [1, 2, 3]

It's up to you how you want to control your code.

Kamil Lelonek
  • 14,592
  • 14
  • 66
  • 90
23

Starting Scala 2.13, the package scala.jdk.CollectionConverters provides asJava via a pimp of Seq and replaces packages scala.collection.JavaConverters/JavaConversions:

import scala.jdk.CollectionConverters._

// val scalaList: List[Int] = List(1, 2, 3)
scalaList.asJava
// java.util.List[Int] = [1, 2, 3]
Xavier Guihot
  • 54,987
  • 21
  • 291
  • 190
9

Pretty old questions, though I will answer, given but most of suggestions are deprecated.

import scala.collection.JavaConversions.seqAsJavaList

val myList = List("a", "b", "c")
val myListAsJavaList = seqAsJavaList[String](myList)
Shirish Kumar
  • 1,532
  • 17
  • 23
6

Update

with scala 2.9.2:

import scala.collection.JavaConversions._
import scala.collection.mutable.ListBuffer
val x: java.util.List[Int] = ListBuffer( List( 1, 2, 3 ): _* )

result

[1, 2, 3]
Guillaume Massé
  • 8,004
  • 8
  • 44
  • 57
1

For single invocations, doing it by hand might be the simplest solution:

val slist = List (1, 2, 3, 4)          
val jl = new java.util.ArrayList [Integer] (slist.size)
slist.foreach (jl.add (_))   

I didn't measure performance.

Stefan W.
  • 11
  • 1
0

Just doing as proposed above produces immutable list even on Java side. The only working solution I've found is this:

def toJList[T](l:List[T]):util.List[T] = {
  val a = new util.ArrayList[T]
  l.map(a.add(_))
  a
 }
Vitamon
  • 538
  • 7
  • 18
-1

Since Scala 2.12.0 JavaConversions has been deprecated.

So the simplest solution for me was :

java.util.Arrays.asList("a","b","c")
elarib
  • 674
  • 1
  • 8
  • 17
  • 1
    This answer does not explain how to use this to convert a scala list into a java list. Arrays.asList can also be problematic as it returns an Arrays.ArrayList which is not a resizable List which can cause some unexpected errors if you think you have a util.ArrayList. – puhlen Jun 01 '17 at 13:56
  • 3
    Deprecation is true, there is `import scala.collection.JavaConverters._` for 2.12.4 – prayagupa Jan 02 '18 at 19:48
  • `scala.jdk.CollectionConverters._`'s `asJava` is the way to go I believe – jaecktec Aug 24 '23 at 11:25