โครงสร้างข้อมูล NET:
บทสนทนาเพิ่มเติมเกี่ยวกับสาเหตุที่ ArrayList และ List แตกต่างกัน
อาร์เรย์
ในฐานะผู้ใช้รายหนึ่งอาร์เรย์คือคอลเล็กชัน "โรงเรียนเก่า" (ใช่อาร์เรย์ถือเป็นคอลเล็กชันแม้ว่าจะไม่ใช่ส่วนหนึ่งของSystem.Collections
) แต่อะไรคือ "โรงเรียนเก่า" เกี่ยวกับอาร์เรย์เมื่อเปรียบเทียบกับคอลเลกชันอื่น ๆ นั่นคือสิ่งที่คุณได้ระบุไว้ในชื่อเรื่องของคุณ (ที่นี่ ArrayList และ List (Of T)) เริ่มต้นด้วยพื้นฐานโดยดูที่อาร์เรย์
ในการเริ่มต้นอาร์เรย์ใน Microsoft .NET คือ "กลไกที่อนุญาตให้คุณจัดการกับรายการ [ที่เกี่ยวข้องกับเหตุผลทางตรรกะ] หลายรายการเป็นคอลเล็กชันเดียว" (ดูบทความที่เชื่อมโยง) นั่นหมายความว่าอย่างไร? อาร์เรย์เก็บสมาชิกแต่ละคน (องค์ประกอบ) เรียงตามลำดับหนึ่งหลังในหน่วยความจำที่มีที่อยู่เริ่มต้น ด้วยการใช้อาร์เรย์เราสามารถเข้าถึงองค์ประกอบที่จัดเก็บตามลำดับโดยเริ่มต้นจากที่อยู่นั้น
นอกเหนือจากนั้นและตรงกันข้ามกับการเขียนโปรแกรมแนวความคิดทั่วไป 101 แล้วอาร์เรย์สามารถค่อนข้างซับซ้อน:
อาร์เรย์สามารถเป็นมิติข้อมูลเดียวหลายมิติหรือ jadded (อาร์เรย์แบบขรุขระมีมูลค่าการอ่าน) อาร์เรย์จะไม่ไดนามิก: เมื่อเริ่มต้นแล้วอาร์เรย์ของขนาดn จะสำรองพื้นที่เพียงพอที่จะเก็บวัตถุจำนวนn จำนวนองค์ประกอบในอาร์เรย์ไม่สามารถเพิ่มหรือลดขนาดได้ Dim _array As Int32() = New Int32(100)
สงวนพื้นที่ว่างเพียงพอบนบล็อกหน่วยความจำสำหรับอาร์เรย์เพื่อให้มีวัตถุชนิดดั้งเดิม 100 Int32 (ในกรณีนี้อาร์เรย์จะถูกเตรียมใช้งานให้มี 0 วินาที) _array
ที่อยู่ของบล็อกนี้ถูกส่งกลับไป
ตามบทความข้อกำหนดทั่วไปของภาษา (CLS) ต้องการให้อาร์เรย์ทั้งหมดเป็นศูนย์ อาร์เรย์ใน. NET สนับสนุนอาร์เรย์ที่ไม่เป็นศูนย์ อย่างไรก็ตามนี่เป็นเรื่องธรรมดาน้อยกว่า อันเป็นผลมาจาก "Common-Ness" ของอาร์เรย์แบบ zero-based Microsoft ได้ใช้เวลาในการปรับประสิทธิภาพให้เหมาะสมที่สุด ดังนั้นมิติเดียวอาร์เรย์ zero-based (SZs) จึงเป็น "พิเศษ" - และเป็นการใช้งานที่ดีที่สุดของอาร์เรย์
อาร์เรย์จะถูกส่งผ่านโดยการอ้างอิงเสมอ (เป็นที่อยู่หน่วยความจำ) - ชิ้นส่วนสำคัญของตัวต่อ Array ที่ต้องรู้ ในขณะที่พวกเขาทำการตรวจสอบขอบเขต (จะโยนข้อผิดพลาด), การตรวจสอบขอบเขตสามารถปิดการใช้งานในอาร์เรย์
อีกครั้งอุปสรรคที่ใหญ่ที่สุดในอาร์เรย์คือพวกเขาไม่ได้ปรับขนาดได้อีกครั้ง พวกเขามีความจุ "คงที่" แนะนำ ArrayList และ List (Of T) กับประวัติของเรา:
ArrayList - รายการที่ไม่ใช่ทั่วไป
The ArrayList (พร้อมด้วยList(Of T)
- แม้ว่าจะมีความแตกต่างที่สำคัญบางอย่างที่นี่อธิบายในภายหลัง) - อาจเป็นความคิดที่ดีที่สุดที่จะเป็นส่วนเสริมถัดไปของคอลเลกชัน (ในแง่กว้าง) ArrayList สืบทอดมาจากส่วนต่อประสานIList (ผู้สืบทอดของ 'ICollection') ArrayLists ตัวเองเป็นbulkier - กำหนดให้มากขึ้นค่าใช้จ่าย - กว่ารายการ
IList
ไม่เปิดใช้งานการใช้งานเพื่อปฏิบัติกับ ArrayLists เป็นรายการขนาดคงที่ (เช่นอาร์เรย์) อย่างไรก็ตามนอกเหนือจากฟังก์ชั่นเพิ่มเติมทั้งหมดที่เพิ่มโดย ArrayLists แล้วไม่มีข้อได้เปรียบที่แท้จริงในการใช้ ArrayLists ที่มีขนาดคงที่ในฐานะ ArrayLists (เหนืออาร์เรย์) ในกรณีนี้จะช้ากว่าอย่างเห็นได้ชัด
จากการอ่านของฉัน ArrayLists ไม่สามารถขรุขระได้: "การใช้อาร์เรย์หลายมิติเป็นองค์ประกอบ ... ไม่รองรับ" อีกครั้งหนึ่งตอกตะปูในโลงศพของ ArrayLists ArrayLists ยังไม่ได้ "พิมพ์" - หมายความว่าทุกอย่างอยู่ภายใต้การ ArrayList Object[]
เป็นเพียงอาร์เรย์แบบไดนามิกของวัตถุที่: สิ่งนี้ต้องการการชกมวยจำนวนมาก (โดยนัย) และการยกเลิกการทำบ็อกซ์ (ชัดเจน) เมื่อใช้ ArrayLists และเพิ่มค่าใช้จ่ายอีกครั้ง
ความคิดที่ไม่พร้อมเพรียง: ฉันคิดว่าฉันจำได้ว่าเคยอ่านหรือเคยได้ยินจากอาจารย์คนหนึ่งของฉันว่า ArrayLists เป็นเด็กแนวความคิดที่ไอ้ความพยายามที่จะย้ายจาก Arrays ไปยังกลุ่มรายการประเภทเช่นในขณะที่ครั้งหนึ่งเคย ตัวเลือกเหล่านี้ไม่ใช่ตัวเลือกที่ดีที่สุดอีกต่อไปเนื่องจากมีการพัฒนาเพิ่มเติมเกี่ยวกับคอลเลกชัน
รายการ (ของ T): ArrayList คืออะไร (และหวังว่าจะเป็น)
ความแตกต่างในการใช้งานหน่วยความจำมีความสำคัญมากพอที่รายการ (ของ Int32) ใช้หน่วยความจำน้อยกว่า ArrayList 56% ที่มีประเภทดั้งเดิมเหมือนกัน (8 MB เทียบกับ 19 MB ในการสาธิตที่เชื่อมโยงของสุภาพบุรุษข้างต้น: เชื่อมโยงอีกครั้งที่นี่ ) นี่คือผลลัพธ์ที่ถูกทบต้นด้วยเครื่อง 64 บิต ความแตกต่างนี้แสดงให้เห็นถึงสองสิ่ง: ประการแรก (1), "วัตถุ" ชนิดบรรจุกล่อง Int32 (ArrayList) มีขนาดใหญ่กว่าชนิดดั้งเดิมดั้งเดิม Int32 (รายการ); วินาที (2), ความแตกต่างเป็นเลขยกกำลังเนื่องจากการทำงานภายในของเครื่อง 64- บิต
ดังนั้นอะไรคือความแตกต่างและรายการ (ของ T)คืออะไร? MSDNกำหนดList(Of T)
เป็น "... รายการวัตถุที่พิมพ์ได้อย่างแข็งแกร่งซึ่งสามารถเข้าถึงได้โดยดัชนี" ความสำคัญที่นี่คือบิต "ที่พิมพ์อย่างรุนแรง": รายการ (ของ T) 'รู้จัก' ประเภทและเก็บวัตถุเป็นชนิดของพวกเขา ดังนั้นInt32
จะถูกเก็บไว้เป็นInt32
และไม่ใช่Object
ประเภท สิ่งนี้ช่วยลดปัญหาที่เกิดจากการชกมวยและการเลิกทำกล่อง
MSDN ระบุความแตกต่างนี้เท่านั้นที่เล่นเมื่อจัดเก็บประเภทดั้งเดิมและไม่ใช่ประเภทอ้างอิง ด้วยความแตกต่างที่เกิดขึ้นจริงในวงกว้าง: มากกว่า 500 องค์ประกอบ สิ่งที่น่าสนใจยิ่งกว่าคือเอกสารของ MSDN อ่านว่า "เพื่อประโยชน์ของคุณในการใช้งานการระบุประเภทของรายการ (ของ T) แทนการใช้คลาส ArrayList .... "
โดยพื้นฐานแล้ว List (Of T) คือ ArrayList แต่ดีกว่า มันเป็น "เทียบเท่าทั่วไป" ของ ArrayList เช่นเดียวกับ ArrayList ไม่รับประกันว่าจะถูกจัดเรียงจนกว่าจะเรียงลำดับ (ไปที่รูป) รายการ (ของ T) ยังมีฟังก์ชั่นเพิ่มเข้ามา