141

I have a Java API that returns a List like:

public List<?> getByXPath(String xpathExpr)

I am using the below scala code:

val lst = node.getByXPath(xpath)

Now if I try scala syntax sugar like:

lst.foreach{ node => ... }

it does not work. I get the error:

value foreach is not a member of java.util.List[?0]

It seems I need to convert Java List to Scala List. How to do that in above context?

Ganesh Jadhav
  • 2,830
  • 1
  • 20
  • 32
ace
  • 11,526
  • 39
  • 113
  • 193
  • 2
    possible duplicate of [Converting Java collection into Scala collection](http://stackoverflow.com/questions/674713/converting-java-collection-into-scala-collection) – Kim Stebel Jun 15 '11 at 11:00
  • @Kim: I'm not sure it's appropriate to close this as a duplicate of that particular question -- that particular question talks about Scala 2.7, and the scala.collection.jcl package doesn't exist anymore in Scala 2.8 and 2.9. – Ken Bloom Jun 15 '11 at 15:08

6 Answers6

186

EDIT: Note that this is deprecated since 2.12.0. Use JavaConverters instead. (comment by @Yaroslav)

Since Scala 2.8 this conversion is now built into the language using:

import scala.collection.JavaConversions._

...

lst.toList.foreach{ node =>   .... }

works. asScala did not work

In 2.12.x use import scala.collection.JavaConverters._

In 2.13.x use import scala.jdk.CollectionConverters._

CervEd
  • 3,306
  • 28
  • 25
ace
  • 11,526
  • 39
  • 113
  • 193
  • 14
    On 2.10.4 I had to import scala.collection.JavaConverters._ otherwise I got "value asScala is not a member of java.util.List[String]" – dranxo May 23 '14 at 23:27
  • 11
    `JavaConversions` are deprecated since 2.12.0. Use `JavaConverters` instead. – Yaroslav Apr 05 '17 at 10:47
  • 5
    For 2.13.x, you need `import scala.jdk.CollectionConverters._` https://scala-lang.org/api/2.13.x/scala/jdk/CollectionConverters$.html – Nikolaos Georgiou Sep 21 '19 at 04:00
98

There's a handy Scala object just for this - scala.collection.JavaConverters

You can do the import and asScala afterwards as follows:

import scala.collection.JavaConverters._

val lst = node.getByXPath(xpath).asScala
lst.foreach{ node =>   .... }

This should give you Scala's Buffer representation allowing you to accomplish foreach.

Jacek Laskowski
  • 72,696
  • 27
  • 242
  • 420
montreal.eric
  • 1,126
  • 7
  • 2
  • 7
    JavaConverters should be preferred over JavaConversions since it makes the conversion explicit (and avoids accidental conversions that may be confusing). (I.e., this is the correct answer) – Mark Sep 18 '14 at 17:34
  • 1
    since scala 2.13 this class is deprecated, too. Use scala.jdk.CollectionConverters instead. – stackunderflow Oct 17 '19 at 19:41
10

I was looking for an answer written in Java and surprisingly couldn't find any clean solutions here. After a while I was able to figure it out so I decided to add it here in case someone else is looking for the Java implementation (I guess it also works in Scala?):

JavaConversions.asScalaBuffer(myJavaList).toList()
Radix
  • 1,317
  • 2
  • 17
  • 32
9

If you have to convert a Java List<ClassA> to a Scala List[ClassB], then you must do the following:

1) Add

import scala.collection.JavaConverters._

2) Use methods asScala, toList and then map

List <ClassA> javaList = ...
var scalaList[ClassB] = javaList.asScala.toList.map(x => new ClassB(x))

3) Add the following to the ClassB constructor that receives ClassA as a parameter:

case class ClassB () {
   def this (classA: ClassA) {
      this (new ClassB (classA.getAttr1, ..., classA.getAttrN))
   }
}
Folusho Oladipo
  • 362
  • 3
  • 11
9

Shortcut to convert java list to scala list

import scala.jdk.CollectionConverters._

myjavaList.asScala.toList

Branislav Lazic
  • 14,388
  • 8
  • 60
  • 85
Xing-Wei Lin
  • 329
  • 3
  • 5
6

Since scala 2.8.1 use JavaConverters._ to convert scala and Java collections using asScala and asJava methods.

import scala.collection.JavaConverters._

javalist.asScala

scalaSeq.asJava

see the Conversion relationship scala doc site

Piro
  • 1,367
  • 2
  • 19
  • 40
user1553728
  • 790
  • 7
  • 6