programing

Scala의 Java 컬렉션에서 반복

projobs 2022. 10. 31. 23:06
반응형

Scala의 Java 컬렉션에서 반복

Apache POI API를 사용하는 스칼라 코드를 작성하고 있습니다.다음 행에 포함된 행을 반복하고 싶습니다.java.util.IteratorSheet 클래스에서 배운 내용입니다.리터레이터를 사용하고 싶다.for each스타일 루프가 있기 때문에 네이티브 스칼라 컬렉션으로 변환하려고 했지만 잘 되지 않습니다.

Scala wrapper 클래스/트레이트를 보고 있습니다만, 올바르게 사용하는 방법을 알 수 없습니다.verbose를 사용하지 않고 Scala의 Java 컬렉션에서 반복하려면 어떻게 해야 합니다.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)
        }
    }
}

Scala 2.8에서는 JavaConversions 객체를 Import하기만 하면 됩니다.JavaConversions 객체는 이미 적절한 변환을 선언하고 있습니다.

import scala.collection.JavaConversions._

이전 버전에서는 작동하지 않습니다.

편집: Scala 2.13.0은 권장하지 않습니다.scala.collection.JavaConverters2.13.0 이후로는scala.jdk.CollectionConverters.

Scala 2.12.0은 권장하지 않음scala.collection.JavaConversions2.12.0 이후로는 다음과 같은 방법이 있습니다.

import scala.collection.JavaConverters._

// ...

for(k <- javaCollection.asScala) {
    // ...
}

( Import에 주의해 주세요.새로운 것은 Java Converters, 권장되지 않는 것은 Java Conversions)

래퍼 클래스가 있습니다(scala.collection.jcl.MutableIterator.Wrapper)를 정의하면

implicit def javaIteratorToScalaIterator[A](it : java.util.Iterator[A]) = new Wrapper(it)

그러면 Scala 반복기의 하위 클래스로 동작하기 때문에foreach.

여기서 정답은 Java에서 암묵적인 변환을 정의하는 것입니다.Iterator커스텀 타입으로 변환합니다.이 타입에서는,foreach기초에 위임하는 방법Iterator이렇게 하면 Scala를 사용할 수 있습니다.for- 임의의 Java에서 루프Iterator.

Scala 2.10의 경우:

// Feature warning if you don't enable implicit conversions...
import scala.language.implicitConversions
import scala.collection.convert.WrapAsScala.enumerationAsScalaIterator

대규모 데이터 세트를 통해 반복하는 경우 전체 컬렉션을 메모리에 로드하지 않을 수 있습니다..asScala암묵적인 변환이 경우 편리한 접근법은 다음과 같은 방법을 구현하는 것입니다.scala.collection.Iterator특성

import java.util.{Iterator => JIterator}

def scalaIterator[T](it: JIterator[T]) = new Iterator[T] {
  override def hasNext = it.hasNext
  override def next() = it.next()
} 

val jIterator: Iterator[String] = ... // iterating over a large dataset
scalaIterator(jIterator).take(2).map(_.length).foreach(println)  // only first 2 elements are loaded to memory

개념은 비슷하지만 IMO의 상세도는 낮습니다.

Scala 2.10.4+(및 그 이전 버전)에서는 java.util을 암묵적으로 변환할 수 있습니다.scala.collection을 반복합니다.scala.collection을 Import하여 반복기 [A]를 만듭니다.JavaConversions.asScalaIterator.다음은 예를 제시하겠습니다.

object SpreadSheetParser2 extends App {

  import org.apache.poi.hssf.usermodel.HSSFWorkbook
  import java.io.FileInputStream
  import scala.collection.JavaConversions.asScalaIterator

  val ios = new FileInputStream("data.xls")
  val workbook = new HSSFWorkbook(ios)
  var sheet = workbook.getSheetAt(0)
  val rows = sheet.rowIterator()

  for (row <- rows) {
    val cells = row.cellIterator()
    for (cell <- cells) {
      print(cell + ",")
    }
    println
  }

}

Java 컬렉션을 배열로 변환하고 다음을 사용할 수 있습니다.

val array = java.util.Arrays.asList("one","two","three").toArray
array.foreach(println)

또는 어레이를 Scala 목록으로 변환합니다.

val list = List.fromArray(array)

scala.collection에서 발생하는 문제를 피하고 싶다면.JavaConversionsscala.collection을 사용할 수 있습니다.명시적으로 변환하는 Java Converters.

scala> val l = new java.util.LinkedList[Int]()
l: java.util.LinkedList[Int] = []

scala> (1 to 10).foreach(l.add(_))

scala> val i = l.iterator
i: java.util.Iterator[Int] = java.util.LinkedList$ListItr@11eadcba

scala> import scala.collection.JavaConverters._
import scala.collection.JavaConverters._

scala> i.asScala.mkString
res10: String = 12345678910

「 」의 .asScala 자바 IteratorIterator.

JavaConverters는 Scala 2.8.1부터 사용할 수 있습니다.

언급URL : https://stackoverflow.com/questions/495741/iterating-over-java-collections-in-scala

반응형