Saya sedang menulis beberapa kode Scala yang menggunakan Apache POI API. Saya ingin mengulang baris yang ada di java.util.Iterator
yang saya dapatkan dari kelas Sheet. Saya ingin menggunakan iterator dalam for each
loop gaya, jadi saya telah mencoba mengubahnya menjadi koleksi Scala asli tetapi tidak berhasil.
Saya telah melihat kelas / sifat pembungkus Scala, tetapi saya tidak dapat melihat cara menggunakannya dengan benar. Bagaimana cara saya mengulang koleksi Java di Scala tanpa menggunakan while(hasNext()) getNext()
gaya loop verbose ?
Berikut kode yang saya tulis berdasarkan jawaban yang benar:
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
sumber
sumber
Jawaban:
Ada kelas pembungkus (
scala.collection.jcl.MutableIterator.Wrapper
). Jadi jika Anda mendefinisikanmaka itu akan bertindak sebagai sub kelas dari iterator Scala sehingga Anda bisa melakukannya
foreach
.sumber
Mulai dari Scala 2.8, yang harus Anda lakukan adalah mengimpor objek JavaConversions, yang sudah mendeklarasikan konversi yang sesuai.
Ini tidak akan berfungsi di versi sebelumnya.
sumber
Edit : Scala 2.13.0 tidak berlaku lagi
scala.collection.JavaConverters
, jadi sejak 2.13.0 Anda perlu menggunakanscala.jdk.CollectionConverters
.Scala 2.12.0 tidak berlaku lagi
scala.collection.JavaConversions
, jadi sejak 2.12.0 salah satu cara untuk melakukannya adalah seperti ini:(perhatikan impornya, baru JavaConverters, usang adalah JavaConversions)
sumber
Jawaban yang benar di sini adalah untuk menentukan konversi implisit dari Java
Iterator
ke beberapa tipe kustom. Jenis ini harus menerapkanforeach
metode yang mendelegasikan ke yang mendasarinyaIterator
. Ini akan memungkinkan Anda menggunakan Scalafor
-loop dengan Java apa punIterator
.sumber
Untuk Scala 2.10:
sumber
Dengan Scala 2.10.4+ (dan mungkin sebelumnya), Anda dapat secara implisit mengonversi java.util.Iterator [A] ke scala.collection.Iterator [A] dengan mengimpor scala.collection.JavaConversions.asScalaIterator. Berikut ini contohnya:
sumber
Anda bisa mengonversi koleksi Java ke array dan menggunakannya:
Atau lanjutkan dan ubah larik menjadi daftar Scala:
sumber
Jika Anda melakukan iterasi melalui kumpulan data yang besar, Anda mungkin tidak ingin memuat seluruh koleksi ke dalam memori dengan
.asScala
konversi implisit. Dalam hal ini, pendekatan cara praktis adalah dengan mengimplementasikanscala.collection.Iterator
sifatIni memiliki konsep yang mirip tetapi IMO kurang verbose :)
sumber
Jika Anda ingin menghindari implikasi dalam scala.collection.JavaConversions, Anda dapat menggunakan scala.collection.JavaConverters untuk mengonversi secara eksplisit.
Perhatikan penggunaan
asScala
metode untuk mengonversi JavaIterator
ke ScalaIterator
.JavaConverters telah tersedia sejak Scala 2.8.1.
sumber
import scala.collection.JavaConverters._
dan kemudianjavaList.iterator().asScala
dari contoh Anda dan berhasil