स्काला में जावा संग्रह के बारे में जानकारी


113

मैं कुछ Scala कोड लिख रहा हूँ जो Apache POI API का उपयोग करता है। मैं इसमें शामिल पंक्तियों पर पुनरावृति करना चाहूंगा java.util.Iteratorजो मुझे शीट वर्ग से प्राप्त होते हैं। मैं एक में itter का उपयोग करना चाहते हैंfor each स्टाइल लूप , इसलिए मैं इसे एक देशी स्काला संग्रह में बदलने की कोशिश कर रहा हूं, लेकिन भाग्य नहीं होगा।

मैंने स्काला रैपर वर्गों / लक्षणों को देखा है, लेकिन मैं उन्हें सही तरीके से उपयोग करने का तरीका नहीं देख सकता। मैं क्रिया का उपयोग किए बिना स्काला में जावा संग्रह पर पुनरावृति कैसे कर सकता हूं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)
        }
    }
}

मैं "वेल पंक्ति <- पंक्तियों के लिए" लाइन को शामिल करने के लिए प्रतीत नहीं कर सकता, {"बिना पार्सर के '' <'वर्ण एक XML टैग है? बैकटिक्स काम नहीं करते हैं
BefittingTheorem

आप IteratirWrapper को स्पष्ट रूप से परिवर्तित करने में सक्षम होना चाहिए, जिससे आपको सिंटैक्स का एक अच्छा सा बचत होगा। स्काला में निहित रूपांतरणों के लिए Google।
डैनियल स्पिवक

जवाबों:


28

एक आवरण वर्ग ( scala.collection.jcl.MutableIterator.Wrapper) है। इसलिए अगर आप परिभाषित करते हैं

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

तो यह स्काला इटरेटर की एक उप वर्ग के रूप में कार्य करेगा ताकि आप कर सकें foreach


इसे पढ़ना चाहिए: scala.collection.jcl.MutableIterator.Wrapper
samg

37
यह उत्तर स्काला 2.8 में अप्रचलित है; देखें stackoverflow.com/questions/2708990/…
एलेक्स आर

256

स्कैला 2.8 के रूप में, आपको बस इतना करना है कि जावाकोनॉर्विंस ऑब्जेक्ट को आयात करना है, जो पहले से ही उपयुक्त रूपांतरणों की घोषणा करता है।

import scala.collection.JavaConversions._

हालांकि यह पिछले संस्करणों में काम नहीं करेगा।


24

संपादित करें : स्कैला 2.13.0 दर्शाती है scala.collection.JavaConverters, इसलिए 2.13.0 के बाद से आपको उपयोग करने की आवश्यकता हैscala.jdk.CollectionConverters

स्केल २.१२.० scala.collection.JavaConversions, ऐसा होता है, इसलिए २.१२.० ऐसा करने का एक तरीका कुछ इस तरह होगा:

import scala.collection.JavaConverters._

// ...

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

(सूचना आयात करें, नया JavaConverters है, पदावनत JavaConversions है)


2
मैं "toScala" ^ _ ^ ढूंढ रहा था!
Profiterole

15

यहां सही उत्तर जावा के Iteratorकुछ कस्टम प्रकार से एक अंतर्निहित रूपांतरण को परिभाषित करना है । इस प्रकार को एक foreachविधि को लागू करना चाहिए जो अंतर्निहित को दर्शाता है Iterator। यह आपको forकिसी भी जावा के साथ स्काला- लूप का उपयोग करने की अनुमति देगा Iterator


9

स्केल 2.10 के लिए:

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

5

Scala 2.10.4+ (और संभवतः पहले) के साथ, यह संभव है कि java.util.Iterator को scala.collection.Iterator में परिवर्तित किया जाए। यहाँ एक उदाहरण है:

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
  }

}

4

आप जावा संग्रह को एक सरणी में बदल सकते हैं और इसका उपयोग कर सकते हैं:

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

या सरणी पर जाएँ और स्केल सूची में कनवर्ट करें:

val list = List.fromArray(array)

4

यदि आप एक बड़े डेटासेट के माध्यम से पुनरावृत्ति कर रहे हैं, तो संभवतः आप पूरे संग्रह को .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 :)


2

आप में implicits से बचने के लिए चाहते हैं, तो scala.collection.JavaConversions आप उपयोग कर सकते scala.collection.JavaConverters स्पष्ट रूप से परिवर्तित करने के लिए।

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जावा Iteratorको स्केल में बदलने के लिए विधि के उपयोग पर ध्यान देंIterator

जावाकॉनवर्टर स्काला 2.8.1 के बाद से उपलब्ध है।


मैंने आपके उदाहरण से उपयोग किया import scala.collection.JavaConverters._ और फिर javaList.iterator().asScalaयह काम किया
कोसीरा - बार्टोज़ कोसरज़ी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.