Iterating over Java collections in Scala
Solution 1
There is a wrapper class (scala.collection.jcl.MutableIterator.Wrapper
). So if you define
implicit def javaIteratorToScalaIterator[A](it : java.util.Iterator[A]) = new Wrapper(it)
then it will act as a sub class of the Scala iterator so you can do foreach
.
Solution 2
As of Scala 2.8, all you have to do is to import the JavaConversions object, which already declares the appropriate conversions.
import scala.collection.JavaConversions._
This won't work in previous versions though.
Solution 3
Edit: Scala 2.13.0 deprecates scala.collection.JavaConverters
, so since 2.13.0 you need to use scala.jdk.CollectionConverters
.
Scala 2.12.0 deprecates scala.collection.JavaConversions
, so since 2.12.0 one way of doing this would be something like:
import scala.collection.JavaConverters._
// ...
for(k <- javaCollection.asScala) {
// ...
}
(notice the import, new is JavaConverters, deprecated is JavaConversions)
Solution 4
The correct answer here is to define an implicit conversion from Java's Iterator
to some custom type. This type should implement a foreach
method which delegates to the underlying Iterator
. This will allow you to use a Scala for
-loop with any Java Iterator
.
Solution 5
For Scala 2.10:
// Feature warning if you don't enable implicit conversions...
import scala.language.implicitConversions
import scala.collection.convert.WrapAsScala.enumerationAsScalaIterator
Related videos on Youtube
BefittingTheorem
Updated on July 08, 2022Comments
-
BefittingTheorem almost 2 years
I'm writing some Scala code which uses the Apache POI API. I would like to iterate over the rows contained in the
java.util.Iterator
that I get from the Sheet class. I would like to use the iterator in afor each
style loop, so I have been trying to convert it to a native Scala collection but will no luck.I have looked at the Scala wrapper classes/traits, but I can not see how to use them correctly. How do I iterate over a Java collection in Scala without using the verbose
while(hasNext()) getNext()
style of loop?Here's the code I wrote based on the correct answer:
class IteratorWrapper[A](iter:java.util.Iterator[A]) { def foreach(f: A => Unit): Unit = { while(iter.hasNext){ f(iter.next) } } } object SpreadsheetParser extends Application { implicit def iteratorToWrapper[T](iter:java.util.Iterator[T]):IteratorWrapper[T] = new IteratorWrapper[T](iter) override def main(args:Array[String]):Unit = { val ios = new FileInputStream("assets/data.xls") val workbook = new HSSFWorkbook(ios) var sheet = workbook.getSheetAt(0) var rows = sheet.rowIterator() for (val row <- rows){ println(row) } } }
-
BefittingTheorem over 15 yearsI can't seem to include the line "for (val row <- rows){" without the parser thinking the '<' character is an XML closing tag? The backticks do not work
-
-
samg over 14 yearsIt should read: scala.collection.jcl.MutableIterator.Wrapper
-
Alex R about 14 yearsThis answer is obsolete in Scala 2.8; see stackoverflow.com/questions/2708990/…
-
kosiara - Bartosz Kosarzycki almost 7 yearsI used
import scala.collection.JavaConverters._
and thenjavaList.iterator().asScala
from your example and it worked -
Profiterole over 5 yearsI was looking for "toScala" ^_^!