ภาพรวม ArrayList:
ArrayList ถูกนำไปใช้ตามอาร์เรย์และเป็นอาร์เรย์แบบไดนามิกที่ความจุสามารถเติบโตได้โดยอัตโนมัติคล้ายกับหน่วยความจำแอปพลิเคชันแบบไดนามิกในภาษา C ซึ่งเพิ่มหน่วยความจำแบบไดนามิก
ArrayList ไม่ปลอดภัยกับเธรดและสามารถใช้ในสภาพแวดล้อมแบบเธรดเดี่ยวเท่านั้น ในสภาพแวดล้อมแบบมัลติเธรดคุณสามารถพิจารณาใช้ฟังก์ชั่นคอลเลกชัน SynchronizedList (รายการ L) เพื่อส่งคืนคลาส ArrayList ที่ปลอดภัยจากเธรดหรือคุณสามารถใช้คลาส copyonWriteArrayList ภายใต้แพ็คเกจพร้อมกันพร้อมกัน
ArrayList ใช้อินเทอร์เฟซแบบ serializable ดังนั้นจึงรองรับการทำให้เป็นอนุกรมสามารถส่งผ่านการทำให้เป็นอนุกรม, ใช้อินเทอร์เฟซแบบสุ่มและรองรับการเข้าถึงแบบสุ่มอย่างรวดเร็ว ในความเป็นจริงมันสามารถเข้าถึงได้อย่างรวดเร็วผ่านหมายเลขซีเรียลตัวย่อยใช้อินเทอร์เฟซ cloneable และสามารถโคลนได้
แต่ละอินสแตนซ์ ArrayList มีความจุซึ่งหมายถึงขนาดของอาร์เรย์ที่ใช้ในการจัดเก็บองค์ประกอบรายการ อย่างน้อยก็เท่ากับขนาดของรายการเสมอ เมื่อองค์ประกอบถูกเพิ่มเข้ากับ ArrayList อย่างต่อเนื่องความสามารถของพวกเขาก็เพิ่มขึ้นโดยอัตโนมัติ การเติบโตอัตโนมัติจะนำมาซึ่งข้อมูลใหม่ไปยังอาร์เรย์ใหม่ดังนั้นหากคุณสามารถทำนายปริมาณข้อมูลได้คุณสามารถระบุความสามารถเมื่อสร้าง ArrayList ก่อนที่จะเพิ่มองค์ประกอบจำนวนมากแอปพลิเคชันยังสามารถใช้การดำเนินการ ensurecapacity เพื่อเพิ่มความสามารถของอินสแตนซ์ ArrayList ซึ่งสามารถลดจำนวนการแจกจ่ายที่เพิ่มขึ้น
โปรดทราบว่าการใช้งานนี้ไม่ได้ซิงโครนัส หากหลายเธรดเข้าถึงอินสแตนซ์ ArrayList ในเวลาเดียวกันและอย่างน้อยหนึ่งเธรดจะแก้ไขโครงสร้างรายการจะต้องอยู่ภายนอกซิงโครไนซ์
มาสร้างบันทึกและสรุปของ Java Arraylist
คลาสสาธารณะ ArrayList <E> { / *** องค์ประกอบที่เก็บคอลเลกชัน** / วัตถุชั่วคราวส่วนตัว [] ElementData; / ** ขนาดองค์ประกอบ*/ ขนาด int ส่วนตัว;กำหนดคลาสทั่วไปอาร์เรย์ของวัตถุและตัวแปรส่วนตัวเพื่อบันทึกจำนวนองค์ประกอบในคอลเลกชัน มีตัวแปรส่วนตัวเพิ่มเติมในข้อความต้นฉบับและฉันไม่รู้ว่าจะใช้อะไรและผู้เขียนไม่มีคำอธิบายหรือพูดถึงมัน ไม่เป็นไรถ้าฉันไม่ได้ใช้มัน
/ ** * เริ่มต้นตามขนาดที่ระบุ * @param InitialCapacity */ ArrayList สาธารณะ (int InitialCapacity) {super (); ถ้า (initialCapacity <= 0) {// ข้อยกเว้นโยน unlegalargumentException ใหม่ ("พารามิเตอร์การเริ่มต้นไม่น้อยกว่า 0"); } else {// เริ่มต้นอาร์เรย์ this.elementData = วัตถุใหม่ [การเริ่มต้นความจุ]; }} / *** การเริ่มต้นเริ่มต้น* / public ArrayList () {this (10); } /*** เริ่มต้นตามคลาสคอลเลกชัน* @param c คลาสที่ต้องสืบทอดอินเตอร์เฟสคอลเลกชัน* /arraylist สาธารณะ (คอลเลกชัน <? ขยาย e> c) {// เริ่มต้น elementData = c.toarray (); size = elementData.length; // แปลงประเภทวัตถุถ้า (elementData.getClass ()! = object []. class) {elementData = array.copyof (ElementData, ขนาด, วัตถุ []. คลาส); - 3 วิธีการเริ่มต้นให้เริ่มต้นอาร์เรย์ตามขนาดเริ่มต้นเริ่มต้นขนาดที่กำหนดและผ่านคลาสที่สืบทอดอินเทอร์เฟซคอลเลกชันคอลเลกชันสำหรับการกำหนดค่าเริ่มต้นการแปลงการแปลง
/ *** คอลเลกชันการขยาย* @param mincapacity*/ โมฆะสาธารณะ ensurecapacity (int mincapacity) {/ ** ขนาดปัจจุบันของอาร์เรย์*/ int oldcapacity = elementData.length; ถ้า (mincapacity> oldcapacity) { /*** แม้ว่าจะไม่ได้ใช้ olddata แต่วิธีนี้เป็นเรื่องเกี่ยวกับการจัดการหน่วยความจำและอาร์เรย์ copyof () วิธีการไม่ปลอดภัยแบบเธรด* olddata หมายถึงตัวแปร elementData ในระหว่างวงจรชีวิตของถ้ามันจะไม่กลับมาใช้ใหม่ การจัดสรรหน่วยความจำ Memory ElementData จากการบุกรุก * เมื่อจุดสิ้นสุดกำลังจะออกหากวงจร OldData สิ้นสุดลงและรีไซเคิล*/ Object OldData [] = ElementData; int newCapacity = (oldcapacity * 3)/2 + 1; // เพิ่ม 50%+1 ถ้า (newcapacity <mincapacity) newCapacity = mincapacity; // ใช้ Arrays.copyof เพื่อคัดลอกองค์ประกอบของคอลเลกชันและสร้างอาร์เรย์ใหม่ elementData = array.copyof, newCapacity); -นี่เป็นวิธีหลัก การขยายตัวของชุดนั้นเป็นการเปรียบเทียบการขยายตัวของอาร์เรย์และขนาดของการรวบรวม mincapacity เพื่อพิจารณาว่าควรขยายหรือไม่ วิธีการ array.copyof () ใช้สำหรับการขยายตัว
ข้อความต้นฉบับมีคำอธิบายโดยละเอียด วิธีนี้คัดลอกเนื้อหาของพารามิเตอร์แรกไปยังอาร์เรย์ใหม่ ขนาดของอาร์เรย์เป็นพารามิเตอร์ที่สองและส่งคืนอาร์เรย์ใหม่ มีความคิดเห็นโดยละเอียดเกี่ยวกับตัวแปรของ Olddata
/ *** ตรวจสอบว่าดัชนีอยู่นอกขอบเขต* @param ดัชนี*/ โมฆะส่วนตัว Rangecheck (ดัชนี int) {ถ้า (ดัชนี> ขนาด || ดัชนี <0) {โยน indexoutofboundsexception ใหม่ ("ตัวบ่งชี้เกินดัชนี:" + ดัชนี + "ขนาด:" + ขนาด); -การค้นหาตัวห้อยเป็น 1 /**
* เพิ่มองค์ประกอบ* เพิ่มองค์ประกอบที่ระบุในตอนท้ายของคอลเลกชัน* @param e องค์ประกอบเพิ่ม* @return*/ บูลีนสาธารณะเพิ่ม (e e) {ensurecapacity (ขนาด+1); ElementData [ขนาด] = E; ขนาด ++; กลับมาจริง; -เพิ่มองค์ประกอบก่อนขยายความจุกำหนดค่าแล้วเพิ่มองค์ประกอบหนึ่ง โปรดทราบว่าขนาดฟิลด์ขนาด+1 ไม่ได้เพิ่มหนึ่ง นี่คือการดำเนินการทางคณิตศาสตร์ดังนั้นจึงจำเป็นต้องเพิ่มในภายหลัง
/ *** เพิ่มองค์ประกอบ* เพิ่มองค์ประกอบลงในตำแหน่งที่ระบุ* @param ดัชนีดัชนีดัชนีดัชนีดัชนีดัชนีองค์ประกอบดัชนีองค์ประกอบดัชนีองค์ประกอบ* @param องค์ประกอบ* @return*/ บูลีนสาธารณะเพิ่ม (ดัชนี int, องค์ประกอบ e) {rangecheck (ดัชนี); ensurecapacity (ขนาด+1); // องค์ประกอบ ElementData เริ่มต้นจากตำแหน่งดัชนีและความยาวของ Size-index, // คัดลอกไปยังอาร์เรย์ ElementData ใหม่เริ่มต้นจากตำแหน่งดัชนีเป็นดัชนี+1 // หมายความว่าองค์ประกอบในตำแหน่งนี้และองค์ประกอบที่ตามมาทั้งหมดจะถูกย้ายโดยตำแหน่งเดียว System.arrayCopy (ElementData, INDEX, ElementData, ดัชนี+1, Size-Index); ElementData [ดัชนี] = องค์ประกอบ; ขนาด ++; // เพิ่มองค์ประกอบหนึ่งคืนจริง; -ความแตกต่างที่นี่คือ System.arrayCopy (ElementData, INDEX, ElementData, ดัชนี+1, Size-index);
นี่เป็นวิธีการภายในของ c ข้อความต้นฉบับโดยละเอียดมีคำอธิบายดังนั้นฉันจะไม่พูดถึงเรื่องนี้ที่นี่ นี่เป็นแกนหลักของ arraylist ทั้งหมดและหลักการการใช้งานภายในของอาร์เรย์ copyof ()
/*** เพิ่มองค์ประกอบทั้งหมด* เพิ่มองค์ประกอบทั้งหมดในคอลเลกชันไปยังจุดสิ้นสุดของรายการนี้ในลำดับขององค์ประกอบที่ส่งคืนโดยตัววนซ้ำของคอลเลกชันที่ระบุ * @param c * @return */ public boolean addall (คอลเลกชัน <? ขยาย e> c) {object [] newElement = c.toArray (); int elementLength = newElement.length; ensureCapacity (ขนาด+elementLength); // จากตัวห้อยของ newElement 0, องค์ประกอบ ElementLength, ElementData Size System.ArrayCopy (newElement, 0, ElementData, ขนาด, ElementLength); ขนาด+= ElementLength; ส่งคืน ElementLength! = 0; -โดยทั่วไปวิธีอื่น ๆ จะทำการประมวลผลที่แตกต่างกันตามสถานการณ์ที่แตกต่างกันเช่นการส่งวัตถุข้อมูลผ่านอินเตอร์เฟสและได้รับความยาวสำหรับการขยายตัวและการคัดลอกข้อมูลไปยังอาร์เรย์ใหม่โดยใช้ระบบและ ArrayCopy
/ *** ระบุตำแหน่งเพิ่มองค์ประกอบทั้งหมด* @param ดัชนีแทรกดัชนีตำแหน่ง* @param c คอลเลกชันองค์ประกอบแทรก* @return*/ บูลีนสาธารณะ addall (ดัชนี int, คอลเลกชัน <? ขยาย e> c) {ถ้า (ดัชนี> ขนาด || ดัชนี <0) {โยนดัชนีใหม่ } object [] newElement = c.toarray (); int elementLength = newElement.length; ensureCapacity (ขนาด+elementLength); int nummoved = size-index; // ตัดสินว่าตำแหน่งการแทรกอยู่ตรงกลางของอาร์เรย์หรือไม่ถ้า (nummoved> 0) {// ย้ายองค์ประกอบทั้งหมดที่อยู่ด้านหลังตำแหน่งการแทรกดัชนีย้อนกลับไปข้างหน้า // แทรกองค์ประกอบ nummoved เริ่มต้นจากดัชนีดัชนีดัชนีดัชนีลงในดัชนี+องค์ประกอบความยาวของ ElementData } // เพิ่ม ElementLength ใน newElement จาก 0 ถึงตำแหน่งที่ดัชนี ElementData เริ่มต้น System.ArrayCopy (newElement, 0, ElementData, INDEX, ElementLength); ขนาด += ElementLength; ส่งคืน ElementLength! = 0; } / ** * ระบุค่าของดัชนี * @param index * @param Element * @return * / Public E Set (INT INDEX, E Element) {RangeCheck (ดัชนี); e oldElement = (e) elementData [ดัชนี]; ElementData [ดัชนี] = องค์ประกอบ; กลับมาเก่า; } / ** * รับค่าตามดัชนี * @param index * @return * / สาธารณะ e รับ (int index) {rangecheck (ดัชนี); return (e) elementData [ดัชนี]; } / *** ลบองค์ประกอบตามตัวห้อย* @param ดัชนี* / สาธารณะ e ลบ (ดัชนี int) {RangeCheck (ดัชนี); e oldElement = (e) elementData [ดัชนี]; / ** จำนวนองค์ประกอบหลังจากตัวห้อยที่ถูกลบ*/ int nummoved = size-index-1; // ถ้ามันถูกย้ายภายในช่วงอาร์เรย์ถ้า (nummoved> 0) system.arraycopy (elementData, ดัชนี+1, elementData, index, nummoved); // ลบ elementData [-size] = null; กลับมาเก่า; } /** * ลบตามองค์ประกอบ * @param obj * @return * /บูลีนสาธารณะลบ (Object obj) {// arraylist อนุญาตให้ null ดังนั้นการประมวลผลการตัดสินจะต้องดำเนินการถ้า (obj == null) {สำหรับ (int index = 0; index กลับมาจริง; }}} else {สำหรับ (int index = 0; index <size; index ++) {ถ้า (obj.equals (elementData [index])) {ลบ (ดัชนี); กลับมาจริง; }}} return false; } / *** ลบองค์ประกอบในช่วงที่ระบุตามตัวห้อย* @param fromIndex เริ่มต้น* @param toindex End* / การป้องกันโมฆะที่ได้รับการป้องกัน (int fromIndex, int toindex) {RangeCheck (FromIndex); Rangecheck (Toindex); // จำนวนองค์ประกอบที่จะย้าย int nummoved = size - toIndex; // ย้ายองค์ประกอบด้านหลัง Toindex ไปยัง FromIndex System.ArrayCopy (ElementData, Toindex, ElementData, FromIndex, Nummoved); // จำนวนองค์ประกอบที่จะลบ int newsize = size- (toindex-fromindex); ในขณะที่ (ขนาด! = newsize) {elementData [-Size] = null; }} / *** ปรับความสามารถของอาร์เรย์ให้เป็นความจุจริง* / โมฆะสาธารณะ trimtosize () {int length = elementData.length; ถ้า (ขนาด <leng) {object [] old = elementData; elementData = arrays.copyof (ElementData, ขนาด); }} / *** แปลงองค์ประกอบการรวบรวมเป็นอาร์เรย์* @return* / วัตถุสาธารณะ [] toarray () {return array.copyof (ElementData, ขนาด); } สาธารณะ <t> t [] toarray (t [] a) {ถ้า (A.Length <size) {return (t []) array.copyof (ElementData, Size, A.getClass ()); } // คัดลอกองค์ประกอบการรวบรวมลงในอาร์เรย์ asystem.arrayCopy (ElementData, 0, a, 0, ขนาด); if (a.length> ขนาด) {สำหรับ (int index = size; index <a.length; index ++) {a [index] = null; }} return a; - โดยพื้นฐานแล้วมันคือทั้งหมดที่เกี่ยวกับการใช้งานอาร์เรย์และการใช้วิธี C เพื่อกำหนดค่าและย้าย คุณสามารถดูข้อความต้นฉบับโดยละเอียด มีปัญหาไม่มากนักในข้อความต้นฉบับยกเว้นตัวแปรส่วนตัวและรหัสสามารถทำงานได้อย่างสมบูรณ์แบบ ความยากลำบากของสิ่งนี้และการใช้ตัวแปร olddata ในวิธีการขยายจะเป็นสองวิธีของระบบ, arraycopy และ arrayist.copy () และการใช้ตัวแปร olddata ในวิธีการขยาย ตัวแปรนี้ดีจริงๆ ในตอนแรกฉันไม่รู้ว่าทำไมฉันถึงใช้มันแบบนี้และฉันจะอธิบายมันในตอนท้ายของข้อความต้นฉบับ
ข้างต้นเป็นตัวอย่างคำอธิบายของการใช้งานของ Java Arraylist ที่แนะนำโดยบรรณาธิการ ฉันหวังว่ามันจะเป็นประโยชน์กับคุณ หากคุณมีคำถามใด ๆ โปรดฝากข้อความถึงฉัน บรรณาธิการจะตอบกลับคุณทันเวลา ขอบคุณมากสำหรับการสนับสนุนเว็บไซต์ Wulin Network!