Perbedaan antara Seq dan Daftar di Scala

299

Saya telah melihat dalam banyak contoh bahwa kadang-kadang Seq sedang digunakan, sementara waktu lain adalah Daftar ...

Apakah ada perbedaan, selain yang pertama adalah tipe Scala dan Daftar yang berasal dari Jawa?

opensas
sumber

Jawaban:

408

Dalam istilah Jawa, Scala adalah SeqJava List, dan Scala adalah ListJava LinkedList.

Perhatikan bahwa itu Seqadalah trait, yang setara dengan Java interface, tetapi dengan yang setara dengan metode bek yang akan datang. Scala's Listadalah kelas abstrak yang diperluas oleh Nildan ::, yang merupakan implementasi konkret dari List.

Jadi, di mana Java Listadalah interface, Scala Listadalah implementasi.

Selain itu, Scala Listtidak dapat diubah, yang tidak terjadi pada LinkedList. Kenyataannya, Java tidak memiliki yang setara dengan koleksi yang tidak dapat diubah (hanya baca saja yang menjamin objek baru tidak dapat diubah, tetapi Anda masih dapat mengubah yang lama, dan, oleh karena itu, yang "hanya baca").

Scala's Listsangat dioptimalkan oleh kompiler dan perpustakaan, dan ini adalah tipe data dasar dalam pemrograman fungsional. Namun, ia memiliki keterbatasan dan itu tidak memadai untuk pemrograman paralel. Hari-hari ini, Vectoradalah pilihan yang lebih baik daripada List, tetapi kebiasaan sulit dihilangkan.

Seqadalah generalisasi yang baik untuk urutan, jadi jika Anda memprogram ke antarmuka, Anda harus menggunakannya. Perhatikan bahwa sebenarnya ada tiga dari mereka: collection.Seq, collection.mutable.Seqdan collection.immutable.Seq, dan itu adalah yang terakhir yang adalah "default" diimpor ke dalam ruang lingkup.

Ada juga GenSeqdan ParSeq. Metode yang terakhir berjalan secara paralel jika memungkinkan, sedangkan yang pertama adalah induk dari keduanya Seqdan ParSeq, menjadi generalisasi yang cocok ketika paralelisme kode tidak menjadi masalah. Keduanya relatif baru diperkenalkan, sehingga orang belum menggunakannya terlalu banyak.

Daniel C. Sobral
sumber
3
RE "Java tidak memiliki padanan dengan koleksi yang tidak dapat diubah" , meskipun Stringbukan koleksi, ini adalah contoh dari kelas yang tidak dapat diubah yang akrab bagi programmer Java.
huynhjl
15
@huynhjl Itu intinya. Saya menggambar paralel antara apa yang ada di Jawa dan apa yang ada di Scala, dan tidak ada konsep koleksi yang bisa berubah / tidak dapat diubah di Jawa.
Daniel C. Sobral
2
Java sebenarnya memiliki padanan koleksi abadi. Ini bukan yang 'diiklankan dengan baik' tetapi di sana dan ketika Anda menggunakan obat generik berat Anda cenderung mendapatkan beberapa UnsupportedOperationExceptionkarena ini. Untuk membuat daftar abadi di Jawa Anda menggunakan Collections.unmodifiableList () dan juga ada metode lain untuk Set, Maps dll. Docs.oracle.com/javase/6/docs/api/java/util/…
jbx
27
@ jbx Tidak benar. Jika Anda menggunakan metode ini, Anda mendapatkan sesuatu objek yang akan membuang pengecualian pada metode yang memodifikasinya, tetapi bukan objek yang tidak dapat diubah . Jika objek asli akan dimodifikasi setelah objek yang tidak dapat dimodifikasi dibuat, objek yang tidak dapat dimodifikasi akan mencerminkan itu. Jadi, tidak dapat dimodifikasi, ya, tidak berubah, tidak.
Daniel C. Sobral
3
@ jbx Metode penerimaan tidak dapat menyimpan referensi ke koleksi yang diterimanya dan menganggapnya tidak akan pernah berubah, dan tidak ada jenis di perpustakaan Java standar yang akan menjamin itu - yaitu kekekalan. Jadi, misalnya, metode penerimaan tidak dapat menjamin keamanan thread. Dan ini bahkan tidak menyentuh karakteristik persisten yang dimungkinkan oleh imutabilitas. Tanpa semua itu, itu tidak bisa disebut "setara".
Daniel C. Sobral
81

Sebuah Seq adalah Iterable yang memiliki urutan didefinisikan elemen. Urutan memberikan metode apply()untuk pengindeksan, mulai dari 0 hingga panjang urutan. Seq memiliki banyak subclass termasuk Queue, Range, List, Stack, dan LinkedList.

Sebuah Daftar adalah Seq yang diimplementasikan sebagai linked list berubah. Ini paling baik digunakan dalam kasus-kasus dengan pola akses terakhir-masuk pertama-keluar (LIFO).

Berikut adalah hierarki kelas koleksi lengkap dari Scala FAQ :

masukkan deskripsi gambar di sini

Ceasar Bautista
sumber
2
Di mana Array (dan ArrayBuffer)? Ini bukan jenis Iterable
Peter Krauss
23

Seqadalah sifat yang Listmengimplementasikan.

Jika Anda mendefinisikan wadah Anda sebagai Seq, Anda dapat menggunakan wadah apa pun yang menerapkan Seqsifat.

scala> def sumUp(s: Seq[Int]): Int = { s.sum }
sumUp: (s: Seq[Int])Int

scala> sumUp(List(1,2,3))
res41: Int = 6

scala> sumUp(Vector(1,2,3))
res42: Int = 6

scala> sumUp(Seq(1,2,3))
res44: Int = 6

Catat itu

scala> val a = Seq(1,2,3)
a: Seq[Int] = List(1, 2, 3)

Hanya bantuan singkat untuk:

scala> val a: Seq[Int] = List(1,2,3)
a: Seq[Int] = List(1, 2, 3)

jika tipe kontainer tidak ditentukan, struktur data yang mendasarinya default ke List.

Akavall
sumber
18

Di Scala, Daftar mewarisi dari Seq, tetapi mengimplementasikan Produk ; di sini adalah definisi Daftar yang tepat :

sealed abstract class List[+A] extends AbstractSeq[A] with Product with ...

[Catatan: yang sebenarnya definisi . Tad sedikit lebih kompleks, untuk fit dengan dan membuat penggunaan kerangka koleksi yang sangat kuat Scala]

Zakelfassi
sumber
0

Seperti yang dikatakan @ daniel-c-sobral, List memperluas sifat Seq dan merupakan kelas abstrak yang diterapkan oleh scala.collection.immutable.$colon$colon(atau ::singkatnya), tetapi secara teknis, pikiran bahwa sebagian besar daftar dan seq yang kami gunakan diinisialisasi dalam bentuk Seq(1, 2, 3)atau List(1, 2, 3)yang keduanya kembali scala.collection.immutable.$colon$colon, maka seseorang dapat menulis:

var x: scala.collection.immutable.$colon$colon[Int] = null
x = Seq(1, 2, 3).asInstanceOf[scala.collection.immutable.$colon$colon[Int]]
x = List(1, 2, 3).asInstanceOf[scala.collection.immutable.$colon$colon[Int]]

Sebagai hasilnya, saya berpendapat bahwa satu-satunya hal yang penting adalah metode yang ingin Anda ungkapkan, misalnya untuk menambahkan Anda dapat menggunakan ::dari Daftar yang saya temukan berlebihan dengan +:dari Seq dan saya pribadi tetap menggunakan Seq secara default.

Profiterol
sumber