ในกรณีใดฉันควรใช้ Array (Buffer) และ List (Buffer) ความแตกต่างเพียงอย่างเดียวที่ฉันรู้คืออาร์เรย์นั้นไม่แปรปรวนและรายการต่าง ๆ แปรปรวน แต่สิ่งที่เกี่ยวกับประสิทธิภาพและลักษณะอื่น ๆ ?
ในกรณีใดฉันควรใช้ Array (Buffer) และ List (Buffer) ความแตกต่างเพียงอย่างเดียวที่ฉันรู้คืออาร์เรย์นั้นไม่แปรปรวนและรายการต่าง ๆ แปรปรวน แต่สิ่งที่เกี่ยวกับประสิทธิภาพและลักษณะอื่น ๆ ?
คำตอบ:
สกาล่าList
เป็นโครงสร้างข้อมูลที่ไม่เปลี่ยนรูป recursive ซึ่งเป็นเช่นโครงสร้างพื้นฐานในสกาล่าที่คุณควร (อาจ) จะใช้มันมากขึ้นกว่าArray
(ซึ่งเป็นจริงแน่นอน - The อนาล็อกไม่เปลี่ยนรูปของArray
เป็นIndexedSeq
)
ถ้าคุณมาจากพื้นหลัง Java แล้วขนานที่เห็นได้ชัดคือเมื่อใช้มากกว่าLinkedList
ArrayList
โดยทั่วไปจะใช้สำหรับรายการที่เคยผ่านการสำรวจก่อนเท่านั้น(และไม่ทราบขนาดล่วงหน้า) ในขณะที่รายการหลังควรใช้รายการที่มีขนาดที่รู้จัก (หรือขนาดสูงสุด) หรือการเข้าถึงแบบสุ่มอย่างรวดเร็วเป็นสิ่งสำคัญ
ListBuffer
ให้การแปลงเวลาคงList
ที่ซึ่งเป็นเหตุผลเดียวที่จะใช้ListBuffer
หากจำเป็นต้องมีการแปลงในภายหลัง
Scala Array
ควรถูกนำไปใช้กับ JVM โดยอาร์เรย์ Java และด้วยเหตุนี้Array[Int]
อาจมีประสิทธิภาพมากกว่า (ในฐานะint[]
) มากกว่า a List[Int]
(ซึ่งจะทำกล่องเนื้อหาของมันยกเว้นว่าคุณกำลังใช้ Scala รุ่นล่าสุดซึ่งมี@specialized
คุณสมบัติใหม่) .
อย่างไรก็ตามฉันคิดว่าการใช้Array
s ใน Scala ควรถูกเก็บไว้ให้น้อยที่สุดเพราะรู้สึกว่าคุณจำเป็นต้องรู้ว่าเกิดอะไรขึ้นภายใต้ประทุนเพื่อตัดสินใจว่าอาเรย์ของคุณจะได้รับการสนับสนุนตามประเภทดั้งเดิมที่ต้องการหรืออาจ ชนิดบรรจุกล่อง
นอกจากคำตอบที่โพสต์แล้วนี่คือรายละเอียดบางอย่าง
ในขณะที่Array[A]
เป็นอักษรอาร์เรย์ Java ที่List[A]
เป็นโครงสร้างข้อมูลที่ไม่เปลี่ยนรูปที่เป็นทั้งNil
(รายการว่างเปล่า) (A, List[A])
หรือประกอบด้วยคู่
ความแตกต่างด้านประสิทธิภาพ
Array List
Access the ith element θ(1) θ(i)
Delete the ith element θ(n) θ(i)
Insert an element at i θ(n) θ(i)
Reverse θ(n) θ(n)
Concatenate (length m,n) θ(n+m) θ(n)
Count the elements θ(1) θ(n)
ความแตกต่างของหน่วยความจำ
Array List
Get the first i elements θ(i) θ(i)
Drop the first i elements θ(n-i) θ(1)
Insert an element at i θ(n) θ(i)
Reverse θ(n) θ(n)
Concatenate (length m,n) θ(n+m) θ(n)
ดังนั้นถ้าคุณต้องการเข้าถึงแบบสุ่มอย่างรวดเร็วจำเป็นต้องนับองค์ประกอบหรือด้วยเหตุผลบางอย่างที่คุณจำเป็นต้องมีการปรับปรุงการทำลายล้างที่เป็นดีกว่าList
Array
list = list.drop(i)
. หรือว่ามีเวทมนตร์บางอย่างอยู่ด้านหลังฝากระโปรง?
drop
ไม่จำเป็นต้องคัดลอกส่วนของรายการที่ไม่ได้ลดลง เช่น(x::xs).drop(1)
เป็นสิ่งxs
ไม่ได้เป็น "คัดลอก" xs
ของ
Array นั้นไม่แน่นอนซึ่งหมายความว่าคุณสามารถเปลี่ยนค่าของแต่ละดัชนีในขณะที่ List (โดยค่าเริ่มต้น) นั้นไม่เปลี่ยนรูปหมายความว่ารายการใหม่จะถูกสร้างขึ้นทุกครั้งที่คุณทำการปรับเปลี่ยน ในกรณีส่วนใหญ่มันเป็นอีกสไตล์ "การทำงาน" เพื่อทำงานร่วมกับประเภทข้อมูลไม่เปลี่ยนรูปและคุณอาจจะลองและใช้รายการที่มีโครงสร้างเหมือนyield
, foreach
, match
และอื่น ๆ
สำหรับคุณลักษณะด้านประสิทธิภาพอาร์เรย์จะเร็วขึ้นด้วยการเข้าถึงองค์ประกอบแบบสุ่มในขณะที่รายการจะเร็วขึ้นเมื่อเตรียม (เพิ่ม) องค์ประกอบใหม่ การพูดซ้ำพวกมันเปรียบได้
iterate over
ต์เพราะแคช