ฉันอ่านประโยคมาก่อนและมันก็ดีมาก มีคนถามว่าการใช้ซอร์สโค้ดการอ่านคืออะไร? เรียนรู้แนวคิดการออกแบบของผู้อื่นเพื่อใช้ฟังก์ชั่นบางอย่างและปรับปรุงระดับการเขียนโปรแกรมของคุณ
ใช่ทุกคนใช้ฟังก์ชั่น คนที่แตกต่างกันมีแนวคิดการออกแบบที่แตกต่างกัน บางคนใช้รหัส 10,000 บรรทัดและบางคนใช้ 5,000 บรรทัด บางคนต้องเรียกใช้รหัสเป็นเวลาหลายสิบวินาทีในขณะที่คนอื่นต้องการเพียงไม่กี่วินาที - มาถึงหัวข้อด้านล่าง
เนื้อหาหลักของบทความนี้:
・ความคิดเห็นโดยละเอียดเกี่ยวกับการดำเนินการของ ArrayList ตาม JDK 1.8
part ส่วนย่อยของตัววน ซ้ำ ยังไม่ได้รับการอธิบายอย่างละเอียดและจะถูกวางไว้ในการตีความซอร์สโค้ดอื่น ๆ ที่นี่เรามุ่งเน้นไปที่การดำเนินการของ ArrayList เอง
・ไม่มีการใช้คำอธิบายประกอบมาตรฐานและการเยื้องของรหัสได้รับการปรับอย่างเหมาะสมเพื่อการแนะนำง่าย
นำเข้า java.util.abstractlist; นำเข้า java.util.arrays; นำเข้า java.util.bitset; นำเข้า java.util.collection; นำเข้า java.util.comparator; นำเข้า java.util.concurrentmodificationException; java.util.nosuchelementexception; นำเข้า java.util.Objects; นำเข้า java.util.randomaccess; นำเข้า java.Util.spliterator; นำเข้า java.util.function.consumer; นำเข้า Java.util.function.predicate; การใช้งานอินเทอร์เฟซรายการที่สามารถปรับขนาดได้ ใช้การดำเนินการรายการที่เป็นทางเลือกทั้งหมดและอนุญาตให้องค์ประกอบทั้งหมดรวมถึง null สามารถทำซ้ำได้ * นอกเหนือจากอินเทอร์เฟซรายการคลาสนี้ยังมีวิธีจัดการขนาดของอาร์เรย์เพื่อจัดเก็บขนาดของอาร์เรย์ในรายการ * * ความซับซ้อนของเวลา: * การโทรไปยังขนาดของวิธีการ, isempty, get, set, iterator และ listiterator เป็นเวลาคงที่ * ความซับซ้อนของเวลาในการเพิ่มและการลบคือ o (n) การดำเนินการอื่น ๆ ทั้งหมดเป็นความซับซ้อนของเวลาเชิงเส้น * * ความจุ: * แต่ละ arrayList มีความจุและขนาดความจุอย่างน้อยความยาวขององค์ประกอบรายการและการเริ่มต้นเริ่มต้นคือ 10. * ความจุสามารถเพิ่มขึ้นโดยอัตโนมัติ * หากคุณรู้ล่วงหน้าว่ามีองค์ประกอบหลายอย่างในอาร์เรย์คุณสามารถเพิ่มกำลังการผลิตล่วงหน้าได้โดยเรียกใช้วิธีการ ensurecapacity () ก่อนที่จะเพิ่มองค์ประกอบเพื่อลดค่าใช้จ่ายของการเติบโตของกำลังการผลิตอัตโนมัติในระยะต่อมา * กำลังการผลิตนี้สามารถเริ่มต้นโดยตัวสร้างที่มีความจุเริ่มต้น * * เธรดไม่ปลอดภัย: * ArrayList ไม่ปลอดภัย * หากจำเป็นต้องนำไปใช้กับ multithreads การซิงโครไนซ์จะต้องทำภายนอก * * modcount: * กำหนดไว้ใน AbstractList: การป้องกันชั่วคราว int modCount = 0; * จำนวนครั้งที่รายการนี้ได้รับการแก้ไขอย่างมีโครงสร้าง การปรับเปลี่ยนโครงสร้างหมายถึงการเปลี่ยนขนาดของรายการหรือรบกวนรายการเพื่อให้การวนซ้ำอย่างต่อเนื่องให้ผลลัพธ์ที่ไม่ถูกต้อง * ฟิลด์นี้ใช้โดยตัววนซ้ำและการใช้งาน iterator reterator ที่ส่งคืนโดยวิธีตัววนซ้ำและ listerator * หากค่าในฟิลด์นี้มีการเปลี่ยนแปลงโดยบังเอิญตัววนซ้ำ (หรือรายการตัววนซ้ำ) จะโยนการแก้ไขพร้อมกันเพื่อตอบสนองต่อถัดไปลบก่อนหน้าตั้งค่าหรือเพิ่มการดำเนินการ * เมื่อต้องเผชิญกับการปรับเปลี่ยนที่เกิดขึ้นพร้อมกันในระหว่างการทำซ้ำมันจะให้พฤติกรรมที่ล้มเหลวอย่างรวดเร็วมากกว่าพฤติกรรมที่ไม่ได้กำหนด * ไม่ว่าจะเป็น subclass ที่ใช้ฟิลด์นี้เป็นทางเลือกหรือไม่ * หาก subclass ต้องการที่จะให้ตัววนซ้ำที่ล้มเหลวอย่างรวดเร็ว (และรายการตัววนซ้ำ) มันจะเพิ่มฟิลด์นี้ลงในวิธีการเพิ่ม (int, e) และลบ (int) วิธี (และวิธีอื่น ๆ ที่มันแทนที่ส่งผลให้การปรับเปลี่ยนโครงสร้างรายการ) * จำนวนการโทรเดียวที่จะเพิ่ม (int, e) หรือลบ (int) ต้องไม่เกิน 1 ไปยังฟิลด์นี้มิฉะนั้นตัววนซ้ำ (และรายการตัววนซ้ำ) จะโยนปลอมพร้อมกันปลอม Exceptions * หากการใช้งานไม่ต้องการให้ตัววนซ้ำที่ล้มเหลวอย่างรวดเร็วฟิลด์นี้สามารถละเว้นได้ * * ชั่วคราว: * โดยค่าเริ่มต้นตัวแปรสมาชิกทั้งหมดของวัตถุจะคงอยู่ ในบางกรณีหากคุณต้องการหลีกเลี่ยงการยังคงมีตัวแปรสมาชิกบางตัวของวัตถุคุณสามารถใช้คำหลักชั่วคราวเพื่อติดแท็กพวกเขาซึ่งเป็นคำที่สงวนไว้ใน Java (JDK 1.8) */คลาสสาธารณะ Arraylist <E> ขยายรายการ AbstractList <e> 8683452581122892189L; // เริ่มต้นความจุเริ่มต้นความจุส่วนตัวคงที่ int default_capacity = 10; // ใช้เพื่อแบ่งปันอินสแตนซ์อาร์เรย์ที่ว่างเปล่าด้วยอินสแตนซ์ที่ว่างเปล่า วัตถุสุดท้ายคงที่ส่วนตัว [] emport_elementData = {}; // อาร์เรย์ว่างเปล่าเริ่มต้นวัตถุสุดท้ายคงที่ [] defaultCapacity_empty_elementData = {}; // สำหรับด้านขวาอาร์เรย์ขององค์ประกอบการอนุญาตการเข้าถึงแพ็คเกจจะถูกเก็บไว้ชั่วคราววัตถุ [] elementData; // ขนาด Java จะเริ่มต้น int เป็น 0 เมื่อสร้างวัตถุขนาดส่วนตัวของวัตถุ // ตั้งค่าตัวสร้างของความสามารถในการเริ่มต้นด้วยจำนวนที่ระบุและจำนวนลบจะส่ง arraylist สาธารณะข้อยกเว้น (int initialcapacity) {ถ้า (initialcapacity> 0) {this.elementData = วัตถุใหม่ [เริ่มต้นความจุ]; } อื่นถ้า (initialCapacity == 0) {this.elementData = emport_elementData; } else {โยน ungloralargumentException ใหม่ ("ความสามารถที่ผิดกฎหมาย:"+initialcapacity); }} // ตัวสร้างเริ่มต้นใช้อาร์เรย์ควบคุมเพื่อเริ่มต้น arrayList สาธารณะ () {this.elementData = defaultCapacity_EMPTY_ELEMENTDATA; } // สร้างรายการที่มีองค์ประกอบในคอลเลกชันตามลำดับของการกลับมาของตัววนซ้ำของคอลเลกชันสาธารณะ arraylist (คอลเลกชัน <? ขยาย e> c) {elementData = c.toArray (); if ((size = elementData.length)! = 0) {// c.toarray อาจ (ข้อผิดพลาด) ไม่ส่งคืนวัตถุ [] (ดูหมายเลขบั๊ก Java 6260652) ถ้า (ElementData.getClass ()! = Object []. class) ElementData = Array.Copyof } else {// ใช้อาร์เรย์ที่ว่างเปล่า this.elementData = emport_elementData; }} // เนื่องจากความจุมักจะมากกว่าจำนวนองค์ประกอบจริง เมื่อหน่วยความจำแน่นคุณสามารถโทรหาวิธีนี้เพื่อลบตำแหน่งที่สงวนไว้และปรับความจุให้เป็นจำนวนองค์ประกอบจริง // หากคุณแน่ใจว่าจะไม่มีการเพิ่มองค์ประกอบคุณสามารถโทรหาวิธีนี้เพื่อบันทึกช่องว่างสาธารณะ trimtosize () {modcount ++; if (size <elementData.Length) {elementData = (size == 0)? empty_elementdata: array.copyof (ElementData, ขนาด); }} // ตั้งค่าความจุอาร์เรย์ที่มีพารามิเตอร์ที่ระบุโมฆะสาธารณะ ensureCapacity (int mincapacity) {// ถ้าอาร์เรย์ว่างเปล่า, prefetch 0, มิฉะนั้นไปที่ค่าเริ่มต้น (10) int minexpand = (elementData! 0: default_capacity; // หากพารามิเตอร์มากกว่าความจุที่ตั้งไว้ล่วงหน้าให้ใช้พารามิเตอร์นี้เพื่อตั้งค่าความจุอาร์เรย์เพิ่มเติมหาก (mincapacity> minexpand) {ensureexplicitCapacity (mincapacity); }} // เมื่อเพิ่มองค์ประกอบให้แน่ใจว่าอาร์เรย์ความจุส่วนตัวเป็นโมฆะส่วนตัว enurecapacityInternal (int mincapacity) {// ใช้ค่าเริ่มต้นและพารามิเตอร์ที่ใหญ่กว่าเป็นค่าความจุที่ตั้งไว้ล่วงหน้าถ้า (elementData == defaultCapacity_ESPTY_ELEMINTDATA) } ensureeExplicitCapacity (mincapacity); } // หากพารามิเตอร์สูงกว่าความจุอาร์เรย์ให้เพิ่มความจุอาร์เรย์เป็นโมฆะส่วนตัว ensureexplicitCapacity (int mincapacity) {modcount ++; if (mincapacity - elementData.length> 0) เติบโต (mincapacity); } // ความจุสูงสุดของอาร์เรย์อาจทำให้หน่วยความจำล้น (ขีด จำกัด ของหน่วยความจำ VM) int สุดท้ายคงที่ max_array_size = integer.max_value - 8; // เพิ่มขีดความสามารถเพื่อให้แน่ใจว่าสามารถเก็บจำนวนองค์ประกอบที่ระบุโดยพารามิเตอร์โมฆะส่วนตัว Grow (int mincapacity) {int oldcapacity = elementData.length; // เพิ่มกำลังการผลิตที่ตั้งไว้ล่วงหน้าโดย half int newcapacity = oldcapacity + (ความเป็นไปได้ oldcapacity >> 1); // ใช้ค่าที่มากขึ้นจากพารามิเตอร์ถ้า (newCapacity - mincapacity <0) // นั่นคือ newCapacity <mincapacity newCapacity = mincapacity; // หากค่าที่ตั้งไว้ล่วงหน้ามากกว่าค่าเริ่มต้นสูงสุดให้ตรวจสอบว่ามันล้นถ้า (newCapacity - max_array_size> 0) newCapacity = hugecapacity (mincapacity); elementData = arrays.copyof (ElementData, newCapacity); } // ตรวจสอบว่ามันล้นหรือไม่ หากไม่มีการล้นให้ส่งคืนค่าจำนวนเต็มสูงสุด (int ใน Java คือ 4 ไบต์ดังนั้นค่าสูงสุดคือ 0x7ffffffff) หรือค่าเริ่มต้นสูงสุดค่าเริ่มต้นส่วนตัวคงที่ int hugecapacity (int mincapacity) {ถ้า (mincapacity <0) // overflow return (mincapacity> max_array_size)? Integer.max_value: max_array_size; } // ส่งคืนขนาดของอาร์เรย์ขนาด int สาธารณะ () {ขนาดคืน; } // เป็นบูลีนสาธารณะที่ว่างเปล่า isempty () {size return == 0; } // ไม่ว่าจะมีตัวเลขหรือไม่ให้บูลีนบูลสาธารณะมี (Object O) {return indexof (o)> = 0; } // ส่งคืนค่าในการปรากฏตัวครั้งแรกของอาร์เรย์และมันจะถูกตัดสินในรูปแบบที่แตกต่างกันโดยขึ้นอยู่กับว่ามันเป็นโมฆะหรือไม่ หากไม่มีอยู่มันจะกลับมา -1 ความซับซ้อนของเวลาคือ O (n) INTEPLEM INT INTEF (OBJECT O) {ถ้า (o == null) {สำหรับ (int i = 0; i <size; i ++) ถ้า (ElementData [i] == null) return i; } else {สำหรับ (int i = 0; i <size; i ++) ถ้า (o.equals (elementData [i])) กลับ i; } return -1; } // ส่งคืนค่าในครั้งสุดท้ายเมื่อปรากฏในอาร์เรย์ หากไม่มีอยู่มันจะกลับมา -1 ความซับซ้อนของเวลาคือ o (n) public int lastindexof (Object o) {ถ้า (o == null) {สำหรับ (int i = size-1; i> = 0; i--) ถ้า (elementData [i] == null) return i; } else {สำหรับ (int i = size-1; i> = 0; i--) ถ้า (o.equals (elementData [i])) กลับ i; } return -1; } // ส่งคืนสำเนาองค์ประกอบของตัวเองยังไม่ได้รับการคัดลอกและข้อยกเว้นจะถูกโยนเมื่ออาร์เรย์ของกระบวนการคัดลอกเปลี่ยนโคลนวัตถุสาธารณะ () {ลอง {arraylist <?> v = (arraylist <?>) super.clone (); V.ElementData = array.copyof (ElementData, ขนาด); V.ModCount = 0; กลับ V; } catch (clonenotsupportedException e) {โยนใหม่ภายใน (e); }} // แปลงเป็นอาร์เรย์วัตถุใช้ array.copyof () เมธอดวัตถุสาธารณะ [] toarray () {return array.copyof (ElementData, ขนาด); } // ส่งคืนอาร์เรย์ให้ใช้รันไทม์เพื่อกำหนดประเภทและอาร์เรย์มีองค์ประกอบทั้งหมดในรายการนี้ (จากองค์ประกอบแรกถึงองค์ประกอบสุดท้าย) // ความจุอาเรย์ที่ส่งคืนจะถูกกำหนดโดยพารามิเตอร์และค่าที่ใหญ่กว่าในอาร์เรย์นี้ @suppresswarnings array.copyof (ElementData, Size, A.getClass ()); System.arrayCopy (ElementData, 0, A, 0, ขนาด); if (A.Length> ขนาด) a [size] = null; กลับ A; } // ส่งคืนค่าของตำแหน่งที่ระบุเนื่องจากเป็นอาร์เรย์มันเป็น @suppresswarnings ที่รวดเร็วโดยเฉพาะ ("ไม่ได้ตรวจสอบ") e elementData (ดัชนี int) {return (e) elementData [ดัชนี]; } // ส่งคืนค่าของตำแหน่งที่ระบุ แต่ตรวจสอบว่าจำนวนตำแหน่งเกินความยาวอาร์เรย์สาธารณะ E GET (INT ดัชนี) {RangeCheck (ดัชนี); return elementData (ดัชนี); } // ตั้งค่าตำแหน่งที่ระบุเป็นค่าใหม่และส่งคืนค่าก่อนหน้าตรวจสอบว่าตำแหน่งนี้เกินความยาวอาร์เรย์ที่ตั้งค่า e (ดัชนี int, องค์ประกอบ e) {RangeCheck (ดัชนี); E oldValue = ElementData (ดัชนี); ElementData [ดัชนี] = องค์ประกอบ; กลับ OldValue; } // เพิ่มค่าแรกทำให้มั่นใจได้ว่าบูลีนสาธารณะกำลังการผลิตเพิ่ม (e e) {ensurecapacityInternal (ขนาด + 1); ElementData [ขนาด ++] = E; กลับมาจริง; } // เพิ่มค่าในตำแหน่งที่ระบุและตรวจสอบตำแหน่งที่เพิ่มและความจุสาธารณะเพิ่ม (ดัชนี int, องค์ประกอบ e) {rangecheckforadd (ดัชนี); ensurecapacityInternal (ขนาด + 1); // โมฆะคงที่สาธารณะ arraycopy (วัตถุ Src, int srcpos, วัตถุ dest, int destpos, ความยาว int) // src: อาร์เรย์ต้นทาง; SRCPOS: ตำแหน่งเริ่มต้นของอาร์เรย์ต้นทางที่จะคัดลอก; DEST: อาเรย์ปลายทาง; Destpos: ตำแหน่งเริ่มต้นของอาร์เรย์ปลายทาง; ความยาว: สำเนาความยาว System.arrayCopy (ElementData, INDEX, ElementData, ดัชนี + 1, ขนาด - ดัชนี); ElementData [ดัชนี] = องค์ประกอบ; ขนาด ++; } // ลบค่าของตำแหน่งที่ระบุตรวจสอบตำแหน่งที่เพิ่มและส่งคืนค่าก่อนหน้า e ลบ (ดัชนี int) {rangecheck (ดัชนี); Modcount ++; E oldValue = ElementData (ดัชนี); int nummoved = size - ดัชนี - 1; if (nummoved> 0) system.arraycopy (elementData, ดัชนี+1, elementData, ดัชนี, nummoved); ElementData [-size] = null; // ง่ายต่อการรีไซเคิลระยะเวลาการรวบรวมขยะคืน OldValue; } // ลบตำแหน่งที่องค์ประกอบที่ระบุแรกปรากฏขึ้นครั้งแรกบูลีนสาธารณะลบ (วัตถุ o) {ถ้า (o == null) {สำหรับ (int index = 0; index <size; index ++) ถ้า (ElementData [index] == null) {fastremove (ดัชนี); กลับมาจริง; }} else {สำหรับ (int index = 0; index <size; index ++) ถ้า (o.equals (elementData [index])) {fastremove (ดัชนี); กลับมาจริง; }} return false; } // ลบค่าอย่างรวดเร็วที่ตำแหน่งที่ระบุ เหตุผลที่เรียกว่าเร็วควรเป็นไม่จำเป็นต้องตรวจสอบและส่งคืนค่าเพราะมีเพียงโมฆะส่วนตัว fastremove (ดัชนี int) {modcount ++; int nummoved = size - ดัชนี - 1; if (nummoved> 0) system.arraycopy (elementData, ดัชนี+1, elementData, ดัชนี, nummoved); ElementData [-size] = null; // ล้างเพื่อให้ GC ทำงาน} // ล้างอาร์เรย์และตั้งค่าแต่ละค่าเป็น null เพื่ออำนวยความสะดวกในการรวบรวมขยะ (ไม่เหมือนรีเซ็ตขนาดเริ่มต้นของอาร์เรย์จะไม่ถูกรีเซ็ตหากมันเปลี่ยน) โมฆะสาธารณะล้าง () {modcount ++; สำหรับ (int i = 0; i <size; i ++) elementData [i] = null; ขนาด = 0; } // เพิ่มองค์ประกอบของคอลเลกชันไปยังจุดสิ้นสุดหากคอลเลกชันที่จะเพิ่มจะว่างเปล่าให้ส่งคืนบูลีนสาธารณะเท็จ (คอลเลกชัน <? ขยาย e> c) {object [] a = c.toarray (); int numnew = a.length; ensurecapacityInternal (ขนาด + numnew); System.arraycopy (a, 0, elementData, ขนาด, numnew); ขนาด += numnew; ส่งคืน numnew! = 0; } // ฟังก์ชั่นเหมือนกับด้านบนเพิ่มบูลีนสาธารณะ addall (ดัชนี int, คอลเลกชัน <? ขยาย e> c) {rangecheckforadd (ดัชนี); วัตถุ [] a = c.toarray (); // อาร์เรย์ที่จะเพิ่ม int numnew = a.length; // ความยาวของอาร์เรย์ที่จะเพิ่ม ensureCapacityInternal (ขนาด + numnew); // ตรวจสอบความจุ int nummoved = size - index; // ความยาวที่จะไม่ย้าย (ส่วนก่อนหน้า) ถ้า (nummoved> 0) // หากไม่จำเป็นต้องย้ายให้คัดลอกด้วยตัวเองและย้ายส่วนหลังของอาร์เรย์ไปยังระบบตำแหน่งที่ถูกต้อง System.ArrayCopy (A, 0, ElementData, INDEX, NUMNEW); // เพิ่มอาร์เรย์ใหม่ที่อยู่ตรงกลางของขนาดอาร์เรย์ดั้งเดิมที่เปลี่ยนแปลงไป += numNew; ส่งคืน numnew! = 0; } // ลบองค์ประกอบช่วงที่ระบุ พารามิเตอร์คือตำแหน่งเริ่มต้นและจุดสิ้นสุดที่ป้องกันการลบล้างช่องว่าง (int fromindex, int toindex) {modcount ++; int nummoved = size - toindex; // ความยาวที่เก็บรักษาไว้โดยส่วนหลัง System.arrayCopy (ElementData, Toindex, ElementData, FromIndex, Nummoved); int newsize = size - (toindex -fromindex); สำหรับ (int i = newsize; i <size; i ++) {elementData [i] = null; } size = newsize; } // ตรวจสอบว่าจำนวนเกินความยาวของอาร์เรย์เมื่อเพิ่มองค์ประกอบโมฆะส่วนตัว Rangecheck (ดัชนี int) {ถ้า (ดัชนี> = ขนาด) โยน indexoutofboundsexception ใหม่ (outofboundsmsg (ดัชนี)); } // ตรวจสอบว่าโมฆะส่วนตัว RangeCheckForAdd (INT ดัชนี) {ถ้า (ดัชนี> ขนาด || ดัชนี <0) โยน indexoutofboundsexception ใหม่ (outofboundsmsg (ดัชนี)); } // รายละเอียดของ String Private String outofboundsmsg (INT ดัชนี)) {return "ดัชนี:"+index+", ขนาด:"+size; } // ลบองค์ประกอบของคอลเลกชันที่ระบุบูลีนบูลีน RemoveAll (คอลเลกชัน <?> c) {objects.requirenonnull (c); // ตรวจสอบว่าพารามิเตอร์เป็น null return batchremove (c, false); } // รักษาเฉพาะองค์ประกอบของคอลเลกชันบูลีนสาธารณะที่ระบุไว้ (คอลเลกชัน <?> c) {objects.requirenonnull (c); กลับ batchremove (c, true); }/** * การตีความซอร์สโค้ดโดย http://anxpp.com/ * @param เสร็จสมบูรณ์เมื่อจริงค่าขององค์ประกอบในคอลเลกชันที่ระบุจะถูกเก็บไว้จากอาร์เรย์และเมื่อเท็จค่าขององค์ประกอบในคอลเลกชันที่ระบุจะถูกลบออกจากอาร์เรย์ * @return องค์ประกอบที่ซ้ำกันในอาร์เรย์จะถูกลบ (แทนที่จะลบเพียงครั้งเดียวหรือหลายครั้ง) และการดำเนินการลบใด ๆ จะส่งคืนจริง */ บูลีนส่วนตัว batchremove (คอลเลกชัน <?> c, บูลีนส่วนประกอบ) {วัตถุสุดท้าย [] elementData = this.elementData; int r = 0, w = 0; บูลีนดัดแปลง = false; ลอง {// transweep ผ่านอาร์เรย์และตรวจสอบว่าคอลเลกชันนี้มีค่าที่สอดคล้องกันย้ายค่าที่จะเก็บไว้ที่ด้านหน้าของอาร์เรย์และค่าสุดท้ายของ W คือจำนวนองค์ประกอบที่จะเก็บไว้ // จุดง่าย ๆ : หากเก็บไว้ให้ย้ายองค์ประกอบเดียวกันไปยังส่วนก่อนหน้า; หากถูกลบให้ย้ายองค์ประกอบต่าง ๆ ไปยังส่วนก่อนหน้าสำหรับ (; r <size; r ++) ถ้า (c.contains (elementData [r]) == ส่วนประกอบ) elementData [w ++] = elementData [r]; } ในที่สุด {// ตรวจสอบให้แน่ใจว่าชิ้นส่วนก่อนที่ข้อยกเว้นจะถูกโยนลงสามารถดำเนินการที่คาดหวังได้ในขณะที่ส่วนที่ไม่ได้ถูกสำรวจจะเชื่อมต่อกับด้านหลัง // r! = ขนาดหมายความว่าข้อผิดพลาดอาจเกิดขึ้น: c.contains (elementData [r]) w += ขนาด - r; } // ถ้า w == ขนาด: หมายความว่าองค์ประกอบทั้งหมดจะถูกเก็บไว้ดังนั้นจึงไม่มีการดำเนินการลบเกิดขึ้นดังนั้นจะส่งคืนเท็จ มิฉะนั้นจริงและอาร์เรย์ // เมื่อ w! = ขนาดจะถูกส่งคืนแม้ว่าการลองบล็อกจะมีข้อยกเว้นการดำเนินการก่อนที่จะมีการโยนข้อยกเว้นเพราะ W เป็นความยาวของส่วนก่อนหน้านี้เสมอและอาร์เรย์จะไม่ถูกสั่งเพราะ (w! = ขนาด) {สำหรับ (int i = w; i <size; modcount += size - w; // จำนวนครั้งที่เปลี่ยนขนาด = w; // ขนาดใหม่คือจำนวนขององค์ประกอบที่ได้รับการแก้ไข modified = true; }} ส่งคืนแก้ไข; } // บันทึกสถานะของอินสแตนซ์อาร์เรย์ไปยังสตรีม (นั่นคือมันเป็นอนุกรม) อาร์เรย์กระบวนการเขียนมีการเปลี่ยนแปลงและข้อยกเว้นจะถูกโยนโมฆะส่วนตัว WriteObject (java.io.ObjectOutputStream S) พ่น java.io.ioException {int คาดหวัง modCount = modCount; S.DefaultWriteObject (); // ดำเนินการตามกระบวนการ deserialization/serialization เริ่มต้น เขียนฟิลด์ที่ไม่ใช่แบบคงที่และไม่ใช่การขนส่งของคลาสปัจจุบันไปยังสตรีมนี้ // เขียนถึงขนาด s.writeInt (ขนาด); // เขียนองค์ประกอบทั้งหมดเพื่อให้ (int i = 0; i <size; i ++) {s.writeObject (elementData [i]); } if (modcount! = คาดว่าจะได้รับ) {โยนใหม่พร้อมกันใหม่ Exception (); }} // ด้านบนเขียนไว้นี่คือการอ่าน โมฆะส่วนตัว readObject (java.io.ObjectInputStream S) พ่น java.io.ioException, classnotFoundException {elementData = emport_elementData; // ดำเนินการตามลำดับเริ่มต้น/กระบวนการ deserialization s.defaultreadObject (); // อ่านในความยาวอาร์เรย์ s.readint (); ถ้า (ขนาด> 0) {ensureCapacityInternal (ขนาด); วัตถุ [] a = elementData; // อ่านในองค์ประกอบทั้งหมดสำหรับ (int i = 0; i <size; i ++) {a [i] = s.readObject (); }}}} // return listiterator ตำแหน่งเริ่มต้นคือพารามิเตอร์ที่ระบุ Public Public Listiterator <e> listiterator (INT ดัชนี) {ถ้า (ดัชนี <0 || ดัชนี> ขนาด) โยน indexoutofboundsexception ใหม่ ("ดัชนี:"+ดัชนี); ส่งคืน listitr ใหม่ (ดัชนี); } // return listiterator ตำแหน่งเริ่มต้นคือ 0 Public listiterator <e> listiterator () {ส่งคืน listitr ใหม่ (0); } // ส่งคืนตัววนซ้ำสามัญสาธารณะตัววนซ้ำ <e> iterator () {return ใหม่ itr (); } // ตัววนซ้ำทั่วไปใช้คลาสส่วนตัว ITR ใช้ Iterator <E> {int Cursor; // เคอร์เซอร์ดัชนีขององค์ประกอบถัดไปการเริ่มต้นเริ่มต้นคือ 0 int lastret = -1; // ตำแหน่งขององค์ประกอบที่เข้าถึงล่าสุดคือ int คาดหวัง modcount = modcount; // กระบวนการวนซ้ำไม่เรียกใช้อาร์เรย์ที่แก้ไขมิฉะนั้นข้อยกเว้นจะถูกโยน // มีบูลีนสาธารณะอื่น Hasnext () {เคอร์เซอร์กลับ! = ขนาด; } // องค์ประกอบถัดไป @suppresswarnings ("ไม่ได้ตรวจสอบ") สาธารณะ e next () {checkforcomodification (); // ตรวจสอบว่าอาร์เรย์ได้รับการแก้ไข int i = เคอร์เซอร์หรือไม่ if (i> = size) โยน nosuchelementException ใหม่ (); Object [] ElementData = ArrayList.his.ElementData; if (i> = elementData.length) โยนใหม่พร้อมกันใหม่ Exception (); เคอร์เซอร์ = i + 1; // ย้ายเคอร์เซอร์ย้อนกลับ Return (E) ElementData [LASTRET = I]; // ตั้งค่าตำแหน่งการเข้าถึงและส่งคืนค่านี้} // ลบโมฆะสาธารณะองค์ประกอบลบ () {ถ้า (lastret <0) โยนใหม่ unlilstateException (); CheckForComodification (); // ตรวจสอบว่าอาร์เรย์ได้รับการแก้ไขหรือไม่ลอง {arrayList.his.remove (Lastret); เคอร์เซอร์ = Lastret; Lastret = -1; คาดว่า ModCount = ModCount; } catch (indexoutofboundsexception ex) {โยนใหม่พร้อมกันใหม่ Exception (); }} @Override @suppresswarnings ("ไม่ได้ตรวจสอบ") โมฆะสาธารณะ foreachremaining (ผู้บริโภค <? super e> ผู้บริโภค) {objects.requirenonnull (ผู้บริโภค); ขนาด int สุดท้าย = arrayList.S.SIZE; int i = เคอร์เซอร์; if (i> = size) {return; } วัตถุสุดท้าย [] elementData = arrayList.his.elementData; if (i> = elementData.Length) {โยนใหม่พร้อมกันใหม่ Exception (); } ในขณะที่ (i! = size && modcount == คาดหวัง modcount) {consumer.accept ((e) elementData [i ++]); } เคอร์เซอร์ = i; Lastret = i - 1; checkforcomodification (); } // ตรวจสอบว่าอาร์เรย์ได้รับการแก้ไขเป็นโมฆะสุดท้าย checkforcomodification () {ถ้า (modcount! = คาดหวัง modcount) โยนใหม่พร้อมกันใหม่ Exception (); }} // listiterator iterator ใช้คลาสส่วนตัว listitr ขยาย itr onplement listiterator <e> {listitr (ดัชนี int) {super (); เคอร์เซอร์ = ดัชนี; } บูลีนสาธารณะ hasprevious () {กลับเคอร์เซอร์! = 0; } public int nextindex () {กลับเคอร์เซอร์; } public int preventIndex () {กลับเคอร์เซอร์ - 1; } @suppresswarnings ("ไม่ได้ตรวจสอบ") สาธารณะก่อนหน้า () {checkForcomodification (); int i = เคอร์เซอร์ - 1; ถ้า (i <0) โยน nosuchelementexception ใหม่ (); Object [] ElementData = ArrayList.his.ElementData; if (i> = elementData.length) โยนใหม่พร้อมกันใหม่ Exception (); เคอร์เซอร์ = i; return (e) elementData [lastret = i]; } โมฆะสาธารณะชุด (e e) {ถ้า (lastret <0) โยน unlueLstateException ใหม่ (); checkforcomodification (); ลอง {arraylist.his.set (Lastret, e); } catch (indexoutofboundsexception ex) {โยนใหม่พร้อมกันใหม่ Exception (); }} โมฆะสาธารณะเพิ่ม (e e) {checkforcomodification (); ลอง {int i = เคอร์เซอร์; arraylist.his.add (i, e); เคอร์เซอร์ = i + 1; Lastret = -1; คาดว่า ModCount = ModCount; } catch (indexoutofboundsexception ex) {โยนใหม่พร้อมกันใหม่ Exception (); }}} // ส่งคืน subarray ของรายการสาธารณะช่วงที่ระบุ <E> sublist (int fromIndex, int toIndex) {SublistrangeCheck (FromIndex, ToIndex, ขนาด); ส่งคืน Sublist ใหม่ (สิ่งนี้ 0, FromIndex, Toindex); } // ความปลอดภัยตรวจสอบโมฆะคงที่ sublistrangeCheck (int fromIndex, int toindex, ขนาด int) {ถ้า (จาก INDEX <0) โยน indexoutofboundsexception ใหม่ ("FromIndex =" + FromIndex); if (toindex> ขนาด) โยน indexoutofboundsexception ใหม่ ("toindex =" + toindex); ถ้า (FromIndex> ToIndex) โยน unglemalargumentException ใหม่ ("FromIndex (" + FromIndex + ")> ToIndex (" + Toindex + ")"); } // Subarray คลาสส่วนตัว Sublist ขยายบทคัดย่อ <e> ใช้แบบสุ่ม {private final AbstractList <E> พาเรนต์; parentoffset int สุดท้ายส่วนตัว; การชดเชย int สุดท้ายส่วนตัว; ขนาด int; Sublist (AbstractList <E> พาเรนต์, int offset, int fromindex, int toindex) {this.parent = parent; this.parentoffset = fromIndex; this.offset = Offset + FromIndex; this.size = toIndex - FromIndex; this.modcount = arraylist.his.modcount; } Public E SET (INT INDEX, E E) {RangeCheck (ดัชนี); checkforcomodification (); E oldValue = arrayList.his.elementData (ออฟเซ็ต + ดัชนี); arrayList.S.ElementData [Offset + INDEX] = E; กลับ OldValue; } สาธารณะ e get (int index) {rangecheck (ดัชนี); checkforcomodification (); return arraylist.his.elementData (ออฟเซ็ต + ดัชนี); } ขนาด int สาธารณะ () {checkforcomodification (); คืนสิ่งนี้ขนาด; } โมฆะสาธารณะเพิ่ม (INT INDEX, E E) {RangeCheckForAdd (ดัชนี); checkforcomodification (); parent.add (parentoffset + index, e); this.modcount = parent.modcount; this.size ++; } สาธารณะ e ลบ (INT ดัชนี) {RangeCheck (ดัชนี); checkforcomodification (); e result = parent.remove (parentoffset + index); this.modcount = parent.modcount; สิ่งนี้ขนาด-; ผลการกลับมา; } การป้องกันโมฆะที่ได้รับการป้องกัน (int fromindex, int toindex) {checkForcomodification (); parent.removerange (Parentoffset + FromIndex, Parentoffset + ToIndex); this.modcount = parent.modcount; this.size - = ToIndex - FromIndex; } บูลีนสาธารณะ addall (คอลเลกชัน <? ขยาย e> c) {return addall (this.size, c); } Public Boolean Addall (INT ดัชนี, คอลเลกชัน <? ขยาย e> c) {RangeCheckForAdd (ดัชนี); int csize = c.size (); ถ้า (csize == 0) ส่งคืนเท็จ; checkforcomodification (); parent.addall (parentoffset + index, c); this.modcount = parent.modcount; this.size += csize; กลับมาจริง; } public iterator <e> iterator () {return listiterator (); } public listiterator <e> listiterator (ดัชนี int สุดท้าย) {checkforcomodification (); Rangecheckforadd (ดัชนี); final int offset = this.offset; ส่งคืน listiterator ใหม่ <e> () {int cursor = index; int lastret = -1; int ที่คาดหวัง modcount = arraylist.his.modcount; บูลีนสาธารณะ hasnext () {กลับเคอร์เซอร์! = sublist.his.size; } @suppresswarnings ("ไม่ได้ตรวจสอบ") สาธารณะ e ถัดไป () {checkForcomodification (); int i = เคอร์เซอร์; if (i> = sublist.s.size) โยน nosuchelementException ใหม่ (); Object [] ElementData = ArrayList.his.ElementData; if (Offset + i> = elementData.length) โยนใหม่พร้อมกันใหม่ Exception (); เคอร์เซอร์ = i + 1; return (e) ElementData [Offset + (Lastret = i)]; } บูลีนสาธารณะ hasprevious () {กลับเคอร์เซอร์! = 0; } @suppresswarnings ("ไม่ได้ตรวจสอบ") สาธารณะก่อนหน้า () {checkForcomodification (); int i = เคอร์เซอร์ - 1; ถ้า (i <0) โยน nosuchelementexception ใหม่ (); Object [] ElementData = ArrayList.his.ElementData; if (Offset + i> = elementData.length) โยนใหม่พร้อมกันใหม่ Exception (); เคอร์เซอร์ = i; return (e) ElementData [Offset + (Lastret = i)]; } @suppresswarnings ("ไม่ได้ตรวจสอบ") โมฆะสาธารณะ foreachremaining (ผู้บริโภค <? super e> ผู้บริโภค) {objects.requirenonnull (ผู้บริโภค); ขนาด int สุดท้าย = sublist.size; int i = เคอร์เซอร์; if (i> = size) {return; } วัตถุสุดท้าย [] elementData = arrayList.his.elementData; if (Offset + i> = elementData.Length) {โยนใหม่พร้อมกันใหม่ Exception (); } ในขณะที่ (i! = size && modcount == คาดหวัง modcount) {consumer.accept ((e) elementData [Offset+(i ++)]); } // อัปเดตหนึ่งครั้งเมื่อสิ้นสุดการทำซ้ำเพื่อลดการเขียนทราฟฟ์ LASTRET = CURSOR = I; checkforcomodification (); } public int nextindex () {กลับเคอร์เซอร์; } public int preventIndex () {กลับเคอร์เซอร์ - 1; } โมฆะสาธารณะลบ () {ถ้า (lastret <0) โยน unlueLstateException ใหม่ (); checkforcomodification (); ลอง {sublist.his.his.remove (Lastret); เคอร์เซอร์ = Lastret; Lastret = -1; คาดหวัง modcount = arraylist.his.modcount; } catch (indexoutofboundsexception ex) {โยนใหม่พร้อมกันใหม่ Exception (); }} ชุดโมฆะสาธารณะ (E E) {ถ้า (Lastret <0) โยน unlueLstateException ใหม่ (); checkforcomodification (); ลอง {arraylist.his.set (ออฟเซ็ต + Lastret, e); } catch (indexoutofboundsexception ex) {โยนใหม่พร้อมกันใหม่ Exception (); }} โมฆะสาธารณะเพิ่ม (e e) {checkforcomodification (); ลอง {int i = เคอร์เซอร์; sublist.his.add (i, e); เคอร์เซอร์ = i + 1; Lastret = -1; คาดหวัง modcount = arraylist.his.modcount; } catch (indexoutofboundsexception ex) {โยนใหม่พร้อมกันใหม่ Exception (); }} void สุดท้าย checkForComodification () {ถ้า (คาดหวัง modcount! = arraylist.his.modcount) โยนใหม่พร้อมกันใหม่ Exception (); - } รายการสาธารณะ <e> sublist (int fromindex, int toindex) {SublistrangeCheck (FromIndex, ToIndex, ขนาด); ส่งคืน Sublist ใหม่ (นี่, ชดเชย, จาก Inindex, Toindex); } โมฆะส่วนตัว RangeCheck (INT ดัชนี) {ถ้า (ดัชนี <0 || ดัชนี> = this.size) โยน indexoutofboundsexception ใหม่ (outofboundsmsg (ดัชนี)); } โมฆะส่วนตัว RangeCheckForAdd (INT ดัชนี) {ถ้า (ดัชนี <0 || ดัชนี> this.size) โยน indexoutofboundsexception ใหม่ (outofboundsmsg (ดัชนี)); } สตริงส่วนตัว outofboundsmsg (ดัชนี int) {return "ดัชนี:"+index+", ขนาด:"+this.size; } โมฆะส่วนตัว checkForcomodification () {ถ้า (arraylist.his.modcount! = this.modcount) โยนใหม่พร้อมกันใหม่ Exception (); } public Spliterator <E> splitterator () {checkForcomodification (); ส่งคืน arraylistsPliterator ใหม่ <E> (arrayList.his, ชดเชย, ออฟเซ็ต + this.size, this.modcount); }} @Override โมฆะสาธารณะ foreach (ผู้บริโภค <? super e> การกระทำ) {objects.requirenonnull (การกระทำ); Final Int ที่คาดหวัง modcount = modCount; @suppresswarnings ("ไม่ได้ตรวจสอบ") สุดท้าย e [] elementData = (e []) this.elementData; ขนาด int สุดท้าย = this.size; สำหรับ (int i = 0; modcount == คาดว่าจะได้รับ && i <size; i ++) {action.accept (elementData [i]); } if (modcount! = คาดว่าจะได้รับ) {โยนใหม่พร้อมกันใหม่ Exception (); }}/** * สร้าง <em> <a href = "spliterator.html#binding" rel = "ภายนอก nofollow"> การผูกมัดล่าช้า </a> </em> * และ <em> ล้มเหลวอย่างรวดเร็ว </em> {@link Spliterator} * * <p> รายงาน {@code spliterator} {@link Spliterator#ขนาด}, * {@link Spliterator#subsized} และ {@link Spliterator#สั่งซื้อ} * การใช้งานการใช้งานควรจัดทำเอกสารการรายงานของค่าคุณลักษณะเพิ่มเติมเพิ่มเติม * * @return a {@code spliterator} มากกว่าองค์ประกอบในรายการนี้ * @since 1.8 */ @Override public Spliterator <E> splitterator () {ส่งคืน arraylistSpliterator ใหม่ <> (นี่, 0, -1, 0); } /** แยกจากดัชนีโดยใช้ตัวแยกส่วนที่เริ่มต้นขี้เกียจ * /คลาสสุดท้าย arrayListSpliterator <E> ใช้ Spliterator <E> { / * * หาก ArrayLists ไม่เปลี่ยนรูปหรือไม่เปลี่ยนแปลงโครงสร้าง แต่เราตรวจพบการแทรกแซง * มากในระหว่างการสำรวจในทางปฏิบัติโดยไม่ต้องเสียสละประสิทธิภาพมาก เราพึ่งพา * modcounts เป็นหลัก สิ่งเหล่านี้ไม่ได้รับประกันว่าจะตรวจพบความรุนแรงพร้อมกัน * และบางครั้งก็อนุรักษ์มากเกินไปเกี่ยวกับการรบกวน * ภายในเธรด แต่ตรวจพบปัญหาที่เพียงพอที่จะ * คุ้มค่าในทางปฏิบัติ ในการดำเนินการสิ่งนี้เรา (1) อย่างเกียจคร้าน * เริ่มต้นรั้วและคาดว่าจะได้รับจนกว่าจะถึงจุด * ล่าสุดที่เราต้องมุ่งมั่นต่อรัฐที่เรากำลังตรวจสอบ * จึงปรับปรุงความแม่นยำ (สิ่งนี้ใช้ไม่ได้กับ * sublists ที่สร้างตัวแยกที่มีค่าที่ไม่ใช่ lazy * ปัจจุบัน) (2) เราดำเนินการตรวจสอบเพียงครั้งเดียว เมื่อใช้ foreach * (ตรงข้ามกับตัววนซ้ำ) โดยปกติเราสามารถตรวจจับการรบกวน * หลังจากการกระทำเท่านั้นไม่ใช่ก่อน เพิ่มเติม * การตรวจสอบการเรียกใช้ CME ใช้กับความรุนแรงอื่น ๆ ทั้งหมด * ความรุนแรงของสมมติฐานเช่นอาร์เรย์ NULL หรือ SMALL * ElementData มากเกินไปตามขนาด () ซึ่งอาจเกิดขึ้นได้เนื่องจากการรบกวนเท่านั้น สิ่งนี้จะช่วยให้การวนรอบภายในของ foreach ทำงานโดยไม่ต้องตรวจสอบเพิ่มเติมและ * ช่วยลดความซับซ้อนของแลมบ์ดา แม้ว่าสิ่งนี้จะมีจำนวนการตรวจสอบ * โปรดทราบว่าในกรณีทั่วไปของ * list.stream (). foreach (a) ไม่มีการตรวจสอบหรือการคำนวณอื่น ๆ * เกิดขึ้นที่ใดก็ได้นอกเหนือจากภายใน foreach ตัวเอง วิธีอื่น * ที่ใช้น้อยกว่าที่ใช้งานไม่สามารถใช้ประโยชน์จาก * streamlinings เหล่านี้ส่วนใหญ่ */ arraylist สุดท้ายส่วนตัว <E> รายการ; ดัชนี INT ส่วนตัว // ดัชนีปัจจุบันแก้ไขในรั้วล่วงหน้า/แยกส่วนตัว // -1 จนกระทั่งใช้; จากนั้นหนึ่งในอดีตดัชนีล่าสุด Private Int คาดหวัง // เริ่มต้นเมื่อ Fence Set/ ** สร้างตัวแยกใหม่ครอบคลุมช่วงที่กำหนด*/ arraylistSpliterator (arraylist <e> รายการ, จุดกำเนิด int, int fence, int ที่คาดหวัง // ตกลงถ้า null เว้นแต่จะเดินทาง this.index = Origin; this.fence = Fence; this.expectedModCount = คาดหวัง modCount; } private int getFence () {// เริ่มต้นรั้วเป็นขนาดในการใช้งานครั้งแรก int hi; // (ตัวแปรพิเศษปรากฏในวิธีการ foreach) arraylist <e> lst; if ((hi = fence) <0) {ถ้า ((lst = list) == null) hi = fence = 0; else {คาดหวัง modcount = lst.modcount; hi = fence = lst.size; }} return hi; } public ArrayListSpliterator <E> trysplit () {int hi = getFence (), lo = index, mid = (lo + hi) >>> 1; return (lo> = mid)? NULL: // หารช่วงครึ่งเว้นแต่จะมี ARRAYLISTSPLITERATORTITOR ใหม่ <E> (รายการ, LO, INDEX = MID, ที่คาดหวัง); } public boolean tryAdvance(Consumer<? super E> action) { if (action == null) throw new NullPointerException(); int hi = getFence(), i = index; if (i < hi) { index = i + 1; @SuppressWarnings("unchecked") E e = (E)list.elementData[i]; action.accept(e); if (list.modCount != expectedModCount) throw new ConcurrentModificationException(); กลับมาจริง; } return false; } public void forEachRemaining(Consumer<? super E> action) { int i, hi, mc; // hoist accesses and checks from loop ArrayList<E> lst; Object[] a; if (action == null) throw new NullPointerException(); if ((lst = list) != null && (a = lst.elementData) != null) { if ((hi = fence) < 0) { mc = lst.modCount; hi = lst.size; } else mc = expectedModCount; if ((i = index) >= 0 && (index = hi) <= a.length) { for (; i < hi; ++i) { @SuppressWarnings("unchecked") E e = (E) a[i]; action.accept(e); } if (lst.modCount == mc) return; } } throw new ConcurrentModificationException(); } public long estimateSize() { return (long) (getFence() - index); } public int characteristics() { return Spliterator.ORDERED | Spliterator.SIZED | Spliterator.SUBSIZED; } } @Override public boolean removeIf(Predicate<? super E> filter) { Objects.requireNonNull(filter); // figure out which elements are to be removed // any exception thrown from the filter predicted at this stage // will leave the collection unmodified int removeCount = 0; final BitSet removeSet = new BitSet(size); final int expectedModCount = modCount; final int size = this.size; for (int i=0; modCount == expectedModCount && i < size; i++) { @SuppressWarnings("unchecked") final E element = (E) elementData[i]; if (filter.test(element)) { removeSet.set(i); removeCount++; } } if (modCount != expectedModCount) { throw new ConcurrentModificationException(); } // shift surviving elements left over the spaces left by removed elements final boolean anyToRemove = removeCount > 0; if (anyToRemove) { final int newSize = size - removeCount; for (int i=0, j=0; (i < size) && (j < newSize); i++, j++) { i = removeSet.nextClearBit(i); elementData[j] = elementData[i]; } for (int k=newSize; k < size; k++) { elementData[k] = null; // Let gc do its work } this.size = newSize; if (modCount != expectedModCount) { throw new ConcurrentModificationException(); } modCount++; } return anyToRemove; } @Override @SuppressWarnings("unchecked") public void replaceAll(UnaryOperator<E> operator) { Objects.requireNonNull(operator); final int expectedModCount = modCount; final int size = this.size; for (int i=0; modCount == expectedModCount && i < size; i++) { elementData[i] = operator.apply((E) elementData[i]); } if (modCount != expectedModCount) { throw new ConcurrentModificationException(); } modCount++; } @Override @SuppressWarnings("unchecked") public void sort(Comparator<? super E> c) { final int expectedModCount = modCount; Arrays.sort((E[]) elementData, 0, size, c); if (modCount != expectedModCount) { throw new ConcurrentModificationException(); } modCount++; -สรุป
The above is all about ArrayList source code analysis in Java programming, and I hope it will be helpful to everyone. เพื่อนที่สนใจสามารถอ้างถึงหัวข้ออื่น ๆ ที่เกี่ยวข้องในเว็บไซต์นี้ต่อไป หากมีข้อบกพร่องใด ๆ โปรดฝากข้อความไว้เพื่อชี้ให้เห็น ขอบคุณเพื่อนที่ให้การสนับสนุนเว็บไซต์นี้!