ความแตกต่างระหว่าง Seq และรายการใน Scala


299

ฉันเคยเห็นในตัวอย่างมากมายที่บางครั้งใช้ Seq ในขณะที่เวลาอื่นคือรายการ ...

มีความแตกต่างนอกเหนือจากที่เคยเป็นประเภทสกาล่าและรายชื่อมาจาก Java หรือไม่?

คำตอบ:


408

ในแง่ Java, Scala ของSeqจะเป็นของ Java Listและสกาล่าของListจะเป็นของ LinkedListJava

โปรดทราบว่าSeqนี่คือ a traitซึ่งเทียบเท่ากับ Java interfaceแต่เทียบเท่ากับวิธีการป้องกันแบบใหม่ล่าสุด กาลาฯListเป็นระดับนามธรรมที่ขยายNilและซึ่งมีการใช้งานที่เป็นรูปธรรมของ::List

ดังนั้นที่ของ Java ListคือการinterfaceScala ของListเป็นการดำเนินการ

นอกเหนือจากนั้น Scala ของจะไม่เปลี่ยนรูปซึ่งไม่ได้เป็นกรณีของList LinkedListในความเป็นจริง Java ไม่เทียบเท่ากับคอลเลกชันที่ไม่เปลี่ยนรูปแบบ (สิ่งที่อ่านอย่างเดียวรับประกันได้ว่าวัตถุใหม่ไม่สามารถเปลี่ยนได้ แต่คุณยังสามารถเปลี่ยนอันเก่าได้ดังนั้นจึงเป็น "แบบอ่านอย่างเดียว")

Scala's Listนั้นได้รับการปรับให้เหมาะสมอย่างมากโดยคอมไพเลอร์และไลบรารีและเป็นประเภทข้อมูลพื้นฐานในการเขียนโปรแกรมการทำงาน อย่างไรก็ตามมีข้อ จำกัด และไม่เพียงพอสำหรับการเขียนโปรแกรมแบบขนาน ทุกวันนี้Vectorเป็นตัวเลือกที่ดีกว่าListแต่นิสัยก็ยากที่จะทำลาย

Seqเป็นลักษณะทั่วไปที่ดีสำหรับลำดับดังนั้นหากคุณตั้งโปรแกรมอินเตอร์เฟซคุณควรใช้มัน โปรดทราบว่ามีอยู่สามประการด้วยกัน: collection.Seq, collection.mutable.Seqและcollection.immutable.Seq, และเป็นอันหลังที่เป็น "ค่าเริ่มต้น" ที่นำเข้าสู่ขอบเขต

นอกจากนี้ยังมีและGenSeq ParSeqเมธอดหลังจะทำงานแบบขนานหากเป็นไปได้ในขณะที่วิธีแรกคือพาเรนต์ของทั้งคู่SeqและParSeqเป็นวิธีการทั่วไปที่เหมาะสมสำหรับเมื่อการขนานของโค้ดไม่สำคัญ พวกเขาทั้งคู่เพิ่งถูกนำมาใช้ใหม่ดังนั้นผู้คนจึงยังไม่ค่อยได้ใช้เท่าไหร่


3
RE "Java ไม่มีค่าเทียบเท่ากับคอลเลกชันที่เปลี่ยนรูปไม่ได้"ถึงแม้Stringจะไม่ใช่คอลเล็กชัน แต่เป็นตัวอย่างของคลาสที่ไม่เปลี่ยนรูปซึ่งคุ้นเคยกับโปรแกรมเมอร์ Java
huynhjl

15
@huynhjl นั่นคือจุดที่อยู่ด้านข้าง ฉันกำลังวาดแนวระหว่างสิ่งที่มีอยู่ใน Java และสิ่งที่มีอยู่ใน Scala และมีเพียงแนวคิดของคอลเลกชันที่ไม่แน่นอน / ไม่เปลี่ยนรูปใน Java
Daniel C. Sobral

2
Java นั้นมีคอลเลกชันที่ไม่เปลี่ยนรูปแบบจริงๆ ไม่ใช่ว่า 'โฆษณาอย่างดี' แต่มันอยู่ที่นั่นและเมื่อคุณใช้ยาชื่อสามัญอย่างหนักคุณมีแนวโน้มที่จะถูกโจมตีด้วยUnsupportedOperationExceptionเหตุนี้ เพื่อสร้างรายการที่ไม่เปลี่ยนรูปแบบใน Java คุณใช้ Collections.unmodifiableList () และในทำนองเดียวกันมีวิธีการอื่น ๆ สำหรับชุด Maps แผนที่ ฯลฯdocs.oracle.com/javase/6/docs/api/java/util/ …
jbx

27
@jbx ไม่เป็นความจริง หากคุณใช้วิธีการเหล่านี้คุณจะได้รับวัตถุที่จะส่งข้อยกเว้นในวิธีการแก้ไข แต่ไม่ใช่วัตถุที่ไม่เปลี่ยนรูป หากวัตถุต้นฉบับได้รับการแก้ไขหลังจากสร้างวัตถุที่เปลี่ยนแปลงไม่ได้วัตถุที่ไม่เปลี่ยนแปลงนั้นจะสะท้อนให้เห็น ดังนั้นไม่สามารถแก้ไขได้ใช่ไม่เปลี่ยนรูปไม่
Daniel C. Sobral

3
@jbx วิธีการรับไม่สามารถอ้างอิงถึงคอลเลกชันที่ได้รับและคิดว่ามันจะไม่มีวันเปลี่ยนแปลงและไม่มีประเภทในไลบรารี Java มาตรฐานที่จะรับประกันได้ว่า - นั่นคือความไม่สามารถเปลี่ยนแปลงได้ ตัวอย่างเช่นวิธีการรับนั้นไม่สามารถรับประกันความปลอดภัยของเธรดได้ และสิ่งนี้ไม่แม้แต่จะสัมผัสกับลักษณะถาวรที่เปิดใช้งานโดยการไม่เปลี่ยนรูป หากปราศจากสิ่งเหล่านี้มันจะไม่สามารถเรียกว่า "เทียบเท่า" ได้
Daniel C. Sobral

81

ลำดับเป็น Iterable ที่มีคำสั่งที่กำหนดไว้ขององค์ประกอบ ลำดับให้วิธีการapply()สำหรับการจัดทำดัชนีตั้งแต่ 0 ถึงความยาวของลำดับ Seq มีคลาสย่อยมากมายรวมถึง Queue, Range, List, Stack และ LinkedList

รายการเป็นลำดับที่จะดำเนินการในฐานะที่เป็นรายการที่เชื่อมโยงไม่เปลี่ยนรูป มันใช้ดีที่สุดในกรณีที่มีรูปแบบการเข้าถึงเข้าก่อนออกก่อน (LIFO)

นี่คือลำดับชั้นคลาสการรวบรวมที่สมบูรณ์จากคำถามที่พบบ่อย Scala :

ป้อนคำอธิบายรูปภาพที่นี่


2
Array (และ ArrayBuffer) อยู่ที่ไหน มันไม่ใช่ประเภทของ Iterable
Peter Krauss

23

Seqเป็นลักษณะที่Listใช้

หากคุณกำหนดภาชนะของคุณเป็นSeqคุณสามารถใช้ภาชนะใด ๆ ที่ดำเนินการSeqลักษณะ

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

สังเกตได้ว่า

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

เป็นเพียงมือสั้น ๆ สำหรับ:

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

Listหากประเภทภาชนะที่ไม่ได้ระบุค่าเริ่มต้นพื้นฐานโครงสร้างข้อมูลไปยัง


18

ในกาลาที่สืบทอดรายการจากลำดับ แต่การดำเนินการสินค้า ; นี่คือความหมายที่เหมาะสมของรายการ :

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

[หมายเหตุ: จริงนิยาม . เป็นผู้ตาดบิตซับซ้อนมากขึ้นในการสั่งซื้อเพื่อให้สอดคล้องกับและใช้ประโยชน์จากกรอบคอลเลกชันของสกาล่าที่มีประสิทธิภาพมาก]


0

ดังที่ @ daniel-c-sobral กล่าวว่ารายการจะขยายลักษณะของ Seq และเป็นระดับนามธรรมที่ดำเนินการโดยscala.collection.immutable.$colon$colon(หรือ::สั้น ๆ ) แต่ด้านเทคนิคยังคำนึงถึงว่ารายการและ seqs ส่วนใหญ่ที่เราใช้นั้นจะเริ่มต้นในรูปแบบของSeq(1, 2, 3)หรือList(1, 2, 3)ที่ทั้งสองคืนscala.collection.immutable.$colon$colonดังนั้นหนึ่งสามารถเขียน:

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]]

เป็นผลให้ฉันเถียงมากกว่าสิ่งเดียวที่สำคัญคือวิธีการที่คุณต้องการเปิดเผยเช่นคุณสามารถใช้ prepend ::จากรายการที่ฉันพบซ้ำซ้อนกับ+:จาก Seq และโดยส่วนตัวฉันติด Seq โดยค่าเริ่มต้น

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.