Estoy escribiendo un código Scala que usa la API de Apache POI . Me gustaría iterar sobre las filas contenidas en el java.util.Iteratorque obtengo de la clase Hoja. Me gustaría usar el iterador en un for eachbucle de estilo, así que he intentado convertirlo en una colección nativa de Scala, pero no tengo suerte.
He mirado las clases / rasgos de envoltura de Scala, pero no puedo ver cómo usarlas correctamente. ¿Cómo iterar sobre una colección de Java en Scala sin usar el while(hasNext()) getNext()estilo detallado de bucle?
Aquí está el código que escribí según la respuesta correcta:
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)
}
}
}
java
scala
collections
scala-java-interop
Brian Heylin
fuente
fuente

Respuestas:
Hay una clase contenedora (
scala.collection.jcl.MutableIterator.Wrapper). Así que si definesentonces actuará como una subclase del iterador Scala para que pueda hacerlo
foreach.fuente
A partir de Scala 2.8, todo lo que tiene que hacer es importar el objeto JavaConversions, que ya declara las conversiones apropiadas.
Sin embargo, esto no funcionará en versiones anteriores.
fuente
Editar : Scala 2.13.0 está obsoleto
scala.collection.JavaConverters, por lo que desde 2.13.0 debe usarscala.jdk.CollectionConverters.Scala 2.12.0 está en desuso
scala.collection.JavaConversions, por lo que desde 2.12.0 una forma de hacer esto sería algo como:(observe la importación, nuevo es JavaConverters, obsoleto es JavaConversions)
fuente
La respuesta correcta aquí es definir una conversión implícita de Java
Iteratora algún tipo personalizado. Este tipo debería implementar unforeachmétodo que delegue al subyacenteIterator. Esto le permitirá utilizar unforbucle de Scala con cualquier JavaIterator.fuente
Para Scala 2.10:
fuente
Con Scala 2.10.4+ (y posiblemente anterior) es posible convertir implícitamente java.util.Iterator [A] en scala.collection.Iterator [A] importando scala.collection.JavaConversions.asScalaIterator. Aquí hay un ejemplo:
fuente
Puede convertir la colección de Java en una matriz y usar eso:
O continúe y convierta la matriz en una lista Scala:
fuente
Si está iterando a través de un conjunto de datos grande, probablemente no desee cargar la colección completa en la memoria con
.asScalaconversión implícita. En este caso, un enfoque práctico es implementar elscala.collection.IteratorrasgoTiene un concepto similar pero menos detallado en mi opinión :)
fuente
Si desea evitar las implicaciones en scala.collection.JavaConversions , puede usar scala.collection.JavaConverters para convertir explícitamente.
Tenga en cuenta el uso del
asScalamétodo para convertir JavaIteratora ScalaIterator.Los JavaConverters están disponibles desde Scala 2.8.1.
fuente
import scala.collection.JavaConverters._y despuésjavaList.iterator().asScalade su ejemplo y funcionó