1. คอลเลกชันใน Java
คลาสคอลเลกชันใน Java เป็นคลาสที่ใช้บ่อยและสะดวกที่สุดในการเขียนโปรแกรม Java ในฐานะคลาสคอนเทนเนอร์คลาสคอลเลกชันสามารถจัดเก็บข้อมูลทุกประเภทและแน่นอนว่ายังสามารถจัดเก็บประเภทที่ระบุร่วมกับยาชื่อสามัญ (แต่ทั่วไปจะใช้ได้เฉพาะในช่วงระยะเวลาการรวบรวมและจะถูกลบในรันไทม์) สิ่งที่เก็บไว้ในคลาสคอลเลกชันเป็นเพียงการอ้างอิงถึงวัตถุไม่ใช่การอ้างอิงถึงวัตถุเอง ความสามารถของคลาสคอลเลกชันสามารถขยายได้ในระหว่างการดำเนินการและยังมีวิธีการที่สะดวกมากมายเช่นการค้นหาสหภาพและจุดตัดของคอลเลกชัน
2. โครงสร้างคลาสคอลเลกชัน
คอลเลกชันใน Java รวมถึงโครงสร้างข้อมูลหลายอย่างเช่นรายการที่เชื่อมโยงคิวตารางแฮช ฯลฯ ในแง่ของโครงสร้างการสืบทอดของชั้นเรียนสามารถแบ่งออกเป็นสองประเภท หนึ่งถูกสืบทอดมาจากอินเทอร์เฟซคอลเลกชัน คอลเลกชันประเภทนี้รวมถึงคลาสคอลเลกชันเช่นรายการชุดและคิว คลาสอื่น ๆ ได้รับการสืบทอดมาจากอินเตอร์เฟสแผนที่ซึ่งส่วนใหญ่รวมถึงคลาสคอลเลกชันที่เกี่ยวข้องกับตารางแฮช มาดูแผนภาพโครงสร้างการสืบทอดของสองหมวดหมู่นี้:
1. รายการตั้งค่าและคิว
เส้นประสีเขียวในรูปแสดงถึงการใช้งานเส้นทึบสีเขียวแสดงถึงการสืบทอดระหว่างอินเทอร์เฟซและเส้นทึบสีน้ำเงินแสดงถึงการสืบทอดระหว่างคลาส
(1) รายการ: เราใช้รายการเพิ่มเติมรวมถึง ArrayList และ LinkedList ความแตกต่างระหว่างสองสิ่งนี้ก็ชัดเจนมากซึ่งสามารถมองเห็นได้จากชื่อของพวกเขา arraylist พื้นฐานถูกนำมาใช้ผ่านอาร์เรย์ดังนั้นความเร็วในการเข้าถึงแบบสุ่มค่อนข้างเร็ว แต่ประสิทธิภาพค่อนข้างต่ำสำหรับกรณีที่จำเป็นต้องเพิ่มและลบบ่อย สำหรับ LinkedList เลเยอร์พื้นฐานจะถูกนำไปใช้ผ่านรายการที่เชื่อมโยงดังนั้นการเพิ่มและการลบการดำเนินการจะเสร็จสมบูรณ์ง่ายขึ้น แต่ประสิทธิภาพของการเข้าถึงแบบสุ่มค่อนข้างต่ำ
ก่อนอื่นให้ดูที่ประสิทธิภาพการแทรกของทั้งคู่:
แพ็คเกจ com.paddx.test.collection; นำเข้า java.util.arraylist; นำเข้า java.util.linkedlist; คลาสสาธารณะ listtest {โมฆะสาธารณะคงที่ (สตริง [] args) {สำหรับ (int i =; i <; LinkedList <integer> (); สำหรับ (int i =; i <; i ++) {linkedList.add (, i);} end long end = system.currentTimeLis (); system.out.println i =; i <; i ++) {arraylist.add (, i);} system.out.println (System.currentTimeMillis () - สิ้นสุด);}}นี่คือผลลัพธ์ของการดำเนินการในท้องถิ่น:
ยี่สิบสาม
1227
จะเห็นได้ว่าในกรณีนี้ประสิทธิภาพการแทรกของ LinkedList นั้นสูงกว่าของ ArrayList แน่นอนว่านี่เป็นสถานการณ์ที่ค่อนข้างรุนแรง มาเปรียบเทียบประสิทธิภาพของการเข้าถึงแบบสุ่มระหว่างสอง:
แพ็คเกจ com.paddx.test.collection; นำเข้า java.util.arraylist; นำเข้า java.util.linkedlist; นำเข้า java.util.random; คลาสสาธารณะ listTest {โมฆะสาธารณะคงที่ (string [] args) {สุ่มสุ่ม = ใหม่ LinkedList <integer> (); สำหรับ (int i =; i <; i ++) {linkedList.add (i);} arrayList <integer> arrayList = new ArrayList <จำนวนเต็ม> (); สำหรับ (int i =; i <; i ++) {arraylist.add (i);} start long = system.currentTimeMillis (); สำหรับ (int i =; i <; i ++) {int j = random.nextint (i+); int k = linkedList.get (j);} end long end = system.currentTimeMillis (); system.out.println (end - start); arraylist.get (j);} system.out.println (System.currentTimeMillis () - สิ้นสุด);}}นี่คือผลลัพธ์ของการดำเนินการของฉัน:
5277
6
เห็นได้ชัดว่าประสิทธิภาพการเข้าถึงแบบสุ่มของ ArrayList นั้นมีขนาดใหญ่กว่า LinkedList หลายคำสั่ง ด้วยรหัสสองชิ้นนี้เราควรจะสามารถทราบความแตกต่างระหว่าง LinkedList และ ArrayList และสถานการณ์การปรับตัวได้อย่างชัดเจนยิ่งขึ้น สำหรับเวกเตอร์มันเป็นเวอร์ชันที่ปลอดภัยของเธรดของ ArrayList ในขณะที่สแต็กสอดคล้องกับโครงสร้างข้อมูลสแต็ก สองนี้ใช้น้อยกว่าดังนั้นฉันจะไม่ยกตัวอย่างที่นี่
(2) คิว: โดยทั่วไปสามารถทำได้โดยตรงโดยใช้ LinkedList นอกจากนี้ยังสามารถเห็นได้จากแผนภาพคลาสข้างต้นที่ LinkedList สืบทอดมาจาก deque ดังนั้น LinkedList จึงมีฟังก์ชั่นของคิวสองปลาย PriorityQueue มีลักษณะโดยการให้ความสำคัญสำหรับแต่ละองค์ประกอบและองค์ประกอบที่มีลำดับความสำคัญสูงจะได้รับความสำคัญจากคิว
(3) ชุด: ความแตกต่างหลักระหว่างชุดและรายการคือชุดนั้นไม่อนุญาตให้องค์ประกอบซ้ำในขณะที่รายการสามารถอนุญาตให้องค์ประกอบซ้ำได้ ในการตัดสินการทำซ้ำขององค์ประกอบเราต้องตัดสินใจตามวิธีแฮชของวัตถุและวิธีการเท่ากับ นี่คือเหตุผลที่เรามักจะแทนที่วิธี HashCode และวิธีการเท่ากับคลาสองค์ประกอบในคอลเลกชัน ลองมาเป็นตัวอย่างเพื่อดูความแตกต่างระหว่างชุดและรายการรวมถึงบทบาทของวิธี HashCode และวิธีการเท่ากับ:
แพ็คเกจ com.paddx.test.collection; นำเข้า java.util.arraylist; นำเข้า java.util.hashset; นำเข้า java.util.set; ชั้นเรียนสาธารณะตั้งถิ่นฐาน บุคคล ("lxp", 20); arraylist <person> list = new Arraylist <person> (); list.add (p1); system.out.println ("-------------"); list.add (p2); system.out.println ("------------ list.size ()); system.out.println ("-------------"); set <person> set = new hashset <person> (); set.add (p1); system.out.println ("------------"); set.add (p2); system.out.println ("---------- size = "+set.size ());} คนคลาสคงที่ {ชื่อสตริงส่วนตัว; อายุ int ส่วนตัว; บุคคลสาธารณะ (ชื่อสตริง, อายุ int) {this.name = name; this.age = อายุ;}@boolean overridepublic เท่ากับ (วัตถุ o) {system.out.out.println ( getClass ()! = o.getClass ()) ส่งคืนเท็จบุคคลบุคคล = (บุคคล) o; return name.equals (person.name);}@overridepublic int hashcode () {system.out.println ("เรียก hashcode () อายุ ="+อายุ); ผลการดำเนินการของรหัสข้างต้นมีดังนี้:
-
-
ขนาดรายการ = 3
---- หารสาย ----
โทร hashcode (), อายุ = 10
-
โทร hashcode (), อายุ = 10
โทร Equals (); name = lxp
-
โทร hashcode (), อายุ = 20
ตั้งค่าขนาด = 2
จากผลลัพธ์จะไม่มีการดำเนินการเพิ่มเติมเมื่อมีการเพิ่มองค์ประกอบลงในรายการและสามารถทำซ้ำได้ ก่อนเข้าร่วมชุดคุณจะต้องดำเนินการวิธี HashCode ก่อน หากค่าที่ส่งคืนมีอยู่แล้วในชุดคุณจะต้องดำเนินการต่อเพื่อดำเนินการวิธีการเท่ากับ หากผลลัพธ์ที่ส่งคืนโดยวิธี Equals นั้นเป็นจริงก็พิสูจน์ได้ว่าองค์ประกอบนั้นมีอยู่แล้วและองค์ประกอบใหม่จะถูกเขียนทับโดยองค์ประกอบเก่า หากค่า hashcode ที่ส่งคืนนั้นแตกต่างกันคุณจะเพิ่มชุดโดยตรง โปรดจำไว้ว่าที่นี่สำหรับองค์ประกอบในคอลเลกชันองค์ประกอบที่มีค่า hashcode ที่แตกต่างกันจะต้องไม่เท่ากัน แต่สำหรับองค์ประกอบที่ไม่เท่ากันมีค่า hashcode อาจเหมือนกัน
ความแตกต่างระหว่าง HashSet และ LinkedHashSet คือหลังสามารถมั่นใจได้ว่าลำดับขององค์ประกอบที่แทรกลงในชุดนั้นสอดคล้องกับลำดับของเอาต์พุต ความแตกต่างระหว่าง Tresset คือการเรียงลำดับของมันถูกเรียงลำดับในตัวเปรียบเทียบและโดยค่าเริ่มต้นมันจะถูกจัดเรียงตามลำดับจากน้อยไปมากตามลำดับของตัวละคร
(4) ITERABLE: จากรูปนี้คุณจะเห็นว่าคลาสคอลเลกชันสืบทอดมาจาก ITERABLE ฟังก์ชั่นของอินเทอร์เฟซนี้คือการให้การสำรวจองค์ประกอบนั่นคือคลาสคอลเลกชันทั้งหมด (ยกเว้นคลาสที่เกี่ยวข้องกับแผนที่) ให้ฟังก์ชันการสำรวจองค์ประกอบ Iterable มีตัววนซ้ำของ Iterator และซอร์สโค้ดของมันมีดังนี้ หากคุณคุ้นเคยกับโหมดตัววนซ้ำควรเข้าใจง่าย
Iterator อินเตอร์เฟสสาธารณะ <E> {บูลีน hasnext (); e next (); void remove ();}2. แผนที่:
ข้อได้เปรียบที่ใหญ่ที่สุดของคอลเลกชันประเภทแผนที่คือประสิทธิภาพการค้นหานั้นค่อนข้างสูงและความซับซ้อนของเวลาของ O (1) สามารถทำได้อย่างเหมาะสม แผนที่ที่ใช้กันมากที่สุดคือ HashMap ความแตกต่างระหว่าง LinkedHashMap และ HashMap คืออดีตสามารถมั่นใจได้ว่าลำดับขององค์ประกอบที่แทรกลงในชุดนั้นสอดคล้องกับลำดับเอาต์พุต ความแตกต่างระหว่างสองและ treemap นี้คือ treemap ถูกจัดเรียงตามค่าคีย์ แน่นอนว่าการดำเนินการพื้นฐานก็มีความแตกต่างที่สำคัญ ตัวอย่างเช่นชั้นพื้นฐานของ HashMap เป็นตารางแฮชในขณะที่ชั้นพื้นฐานของ treemap เป็นต้นไม้ ตอนนี้ดูความแตกต่างระหว่าง Treemap และ LinkedHashMap:
แพ็คเกจ com.paddx.test.collection; นำเข้า java.util.iterator; นำเข้า java.util.linkedhashmap; นำเข้า java.util.map; นำเข้า java.util.treemap; คลาสสาธารณะ maptest linkedMap = ใหม่ linkedHashMap <string, string> (); treemap.put ("b", null); treemap.put ("c", null); treemap.put ("a", null); treeemap.keyset (). iterator (); iter.hasnext ();) {system.out.println ("treemap ="+iter.next ());} system.out.prin tln ("---------- 分割线 ---------"); linkedMap.put ("b", null); linkedMap.put ("c", null); linkedMap.put ("a", null); (iterator <string> iter = linkedmap.keyset (). iterator (); iter.hasnext ();) {system.out.println ("linkedhashmap ="+iter.next ());}}}}} เรียกใช้รหัสด้านบนและผลการดำเนินการมีดังนี้:
treemap = a
treemap = b
treemap = c
-
LinkedHashMap = B
linkedHashMap = c
LinkedHashMap = A
จากผลการดำเนินงานเป็นที่ชัดเจนว่าความแตกต่างระหว่าง Treemap และ LinkedHashMap นั้นเห็นได้อย่างชัดเจน อดีตคือเอาต์พุตโดยการเรียงลำดับสตริงในขณะที่หลังเป็นเอาต์พุตตามลำดับการแทรก ผู้อ่านอย่างระมัดระวังสามารถพบว่าความแตกต่างระหว่าง HashMap และ Treemap นั้นสอดคล้องกับความแตกต่างที่กล่าวถึงก่อนหน้านี้ระหว่าง Hashset และ TreeSet เมื่อทำการวิเคราะห์ซอร์สโค้ดในอนาคตเราจะเห็นได้ว่า HashSet และ Treeset นั้นถูกนำไปใช้เป็นหลักผ่าน HashMap และ Treemap ตามลำดับดังนั้นความแตกต่างของพวกเขาจึงเหมือนกัน ตอนนี้แฮชชัทไม่ค่อยมีการใช้งาน ความแตกต่างที่สำคัญจาก HASHMAP คือ Hashtable คือ Thread-Safe แต่เนื่องจากประสิทธิภาพต่ำมักจะใช้ HASHMAP ในสภาพแวดล้อมแบบมัลติเธรดมักจะใช้งาน MAP ปัจจุบันแทน
3. สรุป
บทความนี้แนะนำกรอบการรวบรวม Java และความสัมพันธ์ในการสืบทอดโดยรวม นอกเหนือจากคลาสข้างต้นแล้วคอลเลกชันยังมีคลาสเครื่องมือสองคลาส: คอลเลกชันและอาร์เรย์ นอกจากนี้การเรียงลำดับในคอลเลกชันนั้นเกี่ยวข้องอย่างใกล้ชิดกับการเปรียบเทียบและตัวเปรียบเทียบ ในบทความที่ตามมาซอร์สโค้ดการใช้งานคลาสที่กล่าวถึงข้างต้นใน JDK จะได้รับการวิเคราะห์ในรายละเอียด