Я пишу код Scala, который использует API Apache POI . Я хотел бы перебрать строки, содержащиеся в том, java.util.Iterator
что я получаю из класса Sheet. Я хотел бы использовать итератор в for each
цикле стилей, поэтому я пытался преобразовать его в собственную коллекцию Scala, но безуспешно.
Я просмотрел классы / свойства оболочки Scala, но не вижу, как их правильно использовать. Как мне перебрать коллекцию Java в Scala без использования подробного while(hasNext()) getNext()
стиля цикла?
Вот код, который я написал на основе правильного ответа:
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
Брайан Хейлин
источник
источник
Ответы:
Есть обертка class (
scala.collection.jcl.MutableIterator.Wrapper
). Итак, если вы определитетогда он будет действовать как подкласс итератора Scala, чтобы вы могли это сделать
foreach
.источник
Что касается Scala 2.8, все, что вам нужно сделать, это импортировать объект JavaConversions, который уже объявляет соответствующие преобразования.
Однако это не будет работать в предыдущих версиях.
источник
Изменить : Scala 2.13.0 устарел
scala.collection.JavaConverters
, поэтому с 2.13.0 вам нужно использоватьscala.jdk.CollectionConverters
.Scala 2.12.0 устарел
scala.collection.JavaConversions
, поэтому, начиная с версии 2.12.0, можно сделать это примерно так:(обратите внимание на импорт, новый - JavaConverters, устаревший - JavaConversions)
источник
Правильный ответ здесь - определить неявное преобразование Java
Iterator
в какой-то настраиваемый тип. Этот тип должен реализовыватьforeach
метод, который делегирует основную частьIterator
. Это позволит вам использоватьfor
цикл Scala с любой JavaIterator
.источник
Для Scala 2.10:
источник
В Scala 2.10.4+ (и, возможно, ранее) можно неявно преобразовать java.util.Iterator [A] в scala.collection.Iterator [A] путем импорта scala.collection.JavaConversions.asScalaIterator. Вот пример:
источник
Вы можете преобразовать коллекцию Java в массив и использовать это:
Или продолжите и преобразуйте массив в список Scala:
источник
Если вы перебираете большой набор данных, вы, вероятно, не захотите загружать всю коллекцию в память с
.asScala
неявным преобразованием. В этом случае удобнее всего реализоватьscala.collection.Iterator
трейтОн имеет аналогичную концепцию, но менее подробный ИМО :)
источник
Если вы хотите избежать последствий в scala.collection.JavaConversions, вы можете использовать scala.collection.JavaConverters для явного преобразования.
Обратите внимание на использование
asScala
метода для преобразования JavaIterator
в ScalaIterator
.Конвертеры JavaConverters доступны начиная с Scala 2.8.1.
источник
import scala.collection.JavaConverters._
а потомjavaList.iterator().asScala
из твоего примера, и это сработало