স্কালায় জাভা সংগ্রহগুলি নিয়ে আইট্রেট করা


113

আমি কয়েকটি স্কেলা কোড লিখছি যা অ্যাপাচি পিওআই এপিআই ব্যবহার করে । আমি java.util.Iteratorশীট শ্রেণি থেকে প্রাপ্ত সারিগুলিতে পুনরাবৃত্তি করতে চাই । আমি 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)
        }
    }
}

আমি "<" অক্ষরটি একটি এক্সএমএল ক্লোজিং ট্যাগ হিসাবে পার্সার না করে "(ভাল সারি <- সারি))" লাইনটি অন্তর্ভুক্ত করতে পারি না? ব্যাকটিকগুলি কাজ করে না
17-15 অপরাহ্নে BefittingTheorem

আপনার যথাযথ সিনট্যাক্স সাশ্রয় করে ইম্পেরেটিকে র‌্যাটারে রূপান্তর করতে সক্ষম হওয়া উচিত। স্কালায় অন্তর্নিহিত রূপান্তরগুলির জন্য গুগল।
ড্যানিয়েল স্পিওক

উত্তর:


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
এই উত্তরটি স্কেলা ২.৮ এ অচল; দেখতে stackoverflow.com/questions/2708990/...
অ্যালেক্স আর

256

স্কেলা ২.৮ অনুসারে আপনাকে যা করতে হবে তা হল জাভা কনভার্সন অবজেক্টটি আমদানি করা, যা ইতিমধ্যে উপযুক্ত রূপান্তরগুলি ঘোষণা করে decla

import scala.collection.JavaConversions._

এটি যদিও পূর্ববর্তী সংস্করণগুলিতে কাজ করবে না।


24

সম্পাদনা করুন : স্কেল ২.১ dep.০ অনুমিত হয় scala.collection.JavaConverters, সুতরাং ২.১13.০ থেকে আপনাকে ব্যবহার করা দরকার scala.jdk.CollectionConverters

স্কেল ২.১২.০ scala.collection.JavaConversionsঅনুমিত হয়, সুতরাং ২.১২.০ থেকে এই কাজের এক উপায় এরকম হবে:

import scala.collection.JavaConverters._

// ...

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

(আমদানির দিকে লক্ষ্য করুন, নতুন জাভা কনভার্টার্স, হ'ল জাভা কনভার্সনগুলি হ্রাস করা হয়েছে)


2
আমি "টুস্কালা" ^ _ ^ খুঁজছিলাম!
প্রোফিটরল

15

এখানে সঠিক উত্তরটি জাভা Iteratorথেকে কিছু কাস্টম প্রকারের মধ্যে অন্তর্নিহিত রূপান্তরকে সংজ্ঞায়িত করা । এই ধরণের এমন একটি foreachপদ্ধতি প্রয়োগ করা উচিত যা অন্তর্নিহিতদের প্রতিনিধিত্ব করে Iterator। এটি আপনাকে যে forকোনও জাভা দিয়ে স্কেল- লুপ ব্যবহার করতে দেয় Iterator


9

স্কেলার ২.১০ এর জন্য:

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

5

স্কেলা ২.১০.৪+ (এবং সম্ভবত পূর্বে) এর সাহায্যে স্পষ্টতই java.util.Iterator [A] কে scala.colલેક્શન রূপান্তর করা সম্ভব te এখানে একটি উদাহরণ:

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বৈশিষ্ট্য কার্যকর করা approach

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

এটির মত ধারণা রয়েছে তবে আইএমও কম রয়েছে :)


2

আপনি যদি স্ক্যালাল কোডোলজেশন এর ফলস্বরূপ এড়াতে চান তবে জাভা কনভার্সনগুলি আপনি স্পষ্টরূপে রূপান্তর করতে 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রূপান্তর করতে পদ্ধতির ব্যবহারের বিষয়টি নোট করুন ।IteratorIterator

জাভা কনভার্টারগুলি স্কেলা ২.৮.১ থেকে পাওয়া যায়।


আমি ব্যবহার করেছি import scala.collection.JavaConverters._ এবং তারপরে javaList.iterator().asScala আপনার উদাহরণ থেকে এবং এটি কাজ করেছিল
কোসিয়ারা - বার্তোসক কোসরজিকি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.