Iterating over Java collections in Scala

85,547

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
Share:
85,547

Related videos on Youtube

BefittingTheorem
Author by

BefittingTheorem

Updated on July 08, 2022

Comments

  • BefittingTheorem
    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 a for 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
      BefittingTheorem over 15 years
      I 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
    samg over 14 years
    It should read: scala.collection.jcl.MutableIterator.Wrapper
  • Alex R
    Alex R about 14 years
    This answer is obsolete in Scala 2.8; see stackoverflow.com/questions/2708990/…
  • kosiara - Bartosz Kosarzycki
    kosiara - Bartosz Kosarzycki almost 7 years
    I used import scala.collection.JavaConverters._ and then javaList.iterator().asScala from your example and it worked
  • Profiterole
    Profiterole over 5 years
    I was looking for "toScala" ^_^!