JavaRush /จาวาบล็อก /Random-TH /สั้น ๆ เกี่ยวกับสิ่งสำคัญ - Java Collections Framework
Viacheslav
ระดับ

สั้น ๆ เกี่ยวกับสิ่งสำคัญ - Java Collections Framework

เผยแพร่ในกลุ่ม

จุดเริ่มต้นของเส้นทาง

วันนี้ฉันอยากจะพูดถึงหัวข้อที่น่าสนใจเช่น “ Java Collections Framework ” หรือพูดง่ายๆ ก็คือเกี่ยวกับคอลเลกชั่น งานของโค้ดส่วนใหญ่กำลังประมวลผลข้อมูลในรูปแบบใดรูปแบบหนึ่ง รับรายชื่อผู้ใช้ รับรายชื่อที่อยู่ ฯลฯ เรียงลำดับ ทำการค้นหา เปรียบเทียบ นี่คือเหตุผลว่าทำไมความรู้เรื่องการสะสมจึงถือเป็นทักษะหลัก นั่นเป็นเหตุผลที่ฉันอยากจะพูดคุยเกี่ยวกับเรื่องนี้ นอกจากนี้ หนึ่งในคำถามที่พบบ่อยที่สุดในการสัมภาษณ์นักพัฒนา Java ก็คือคอลเล็กชัน ตัวอย่างเช่น "วาดลำดับชั้นของคอลเลกชัน" คอมไพเลอร์ออนไลน์จะช่วยเราในการเดินทาง ตัวอย่างเช่น คุณสามารถใช้ " Tutorialspoint Online Java Compiler " หรือRepl.it เส้นทางสู่การทำความรู้จักกับโครงสร้างข้อมูลใดๆ เริ่มต้นด้วยตัวแปรธรรมดา (ตัวแปร) บนเว็บไซต์ของ Oracle หัวข้อต่างๆ จะแสดงเป็น "เส้นทาง" หรือเส้นทาง ดังนั้นเส้นทางสู่การทำความรู้จักกับ Java จึงเรียกว่า “ Trail: Learning the Java Language: Table of Contents ” และพื้นฐานของภาษา (เช่น พื้นฐานภาษา) เริ่มต้นด้วยตัวแปร ดังนั้นเรามาเขียนโค้ดง่ายๆ:
public static void main(String[] args) {
	String user = "Max";
	System.out.println("Hello, " + user);
}
เป็นสิ่งที่ดีในทุกสิ่ง ยกเว้นว่าเราเข้าใจว่าโค้ดนี้ดีและสวยงามสำหรับตัวแปรตัวเดียวเท่านั้น จะทำอย่างไรถ้ามีหลายอัน? อาร์เรย์ถูกประดิษฐ์ขึ้นเพื่อจัดเก็บข้อมูลประเภทเดียว ใน Trail เดียวกันจาก Oracle มีส่วนแยกต่างหากสำหรับอาร์เรย์โดยเฉพาะ ส่วนนี้เรียกว่า: " อาร์เรย์ " การทำงานกับอาร์เรย์ก็ค่อนข้างง่าย:
import java.util.Arrays;
class Main {
  public static void main(String[] args) {
    String[] users = new String[2];
    users[0] = "Max";
    users[1] = "John";
    System.out.println("Hello, " + Arrays.toString(users));
  }
}
อาร์เรย์แก้ปัญหาการจัดเก็บค่าหลายค่าไว้ในที่เดียว แต่มันมีข้อจำกัด: ขนาดอาเรย์คงที่ ดังตัวอย่าง หากเราบอกว่าขนาด = 2 ก็จะเท่ากับ 2 นั่นคือทั้งหมดที่ หากเราต้องการอาร์เรย์ที่ใหญ่ขึ้น เราจำเป็นต้องสร้างอินสแตนซ์ใหม่ นอกจากนี้ การค้นหาองค์ประกอบก็เป็นเรื่องยากสำหรับอาร์เรย์เช่นกัน มีวิธีหนึ่งArrays.binarySearchแต่การค้นหานี้ใช้ได้กับอาร์เรย์ที่เรียงลำดับแล้วเท่านั้น (สำหรับอาร์เรย์ที่ไม่ได้เรียงลำดับ ผลลัพธ์จะไม่ได้กำหนดไว้หรือคาดเดาไม่ได้) นั่นคือการค้นหาจะทำให้เราต้องเรียงลำดับในแต่ละครั้ง การลบจะเป็นการล้างค่าเท่านั้น ดังนั้นเราจึงยังไม่ทราบว่าจริงๆ แล้วมีข้อมูลอยู่ในอาร์เรย์จำนวนเท่าใด เรารู้เพียงจำนวนเซลล์ในอาร์เรย์เท่านั้น หากต้องการรีเฟรชความรู้เกี่ยวกับอาร์เรย์: และจากการพัฒนาภาษา Java ทำให้ Java Collections Framework ปรากฏใน JDK 1.2 ซึ่งเราจะพูดถึงในวันนี้
สั้น ๆ เกี่ยวกับสิ่งสำคัญ - Java Collections Framework - 2

ของสะสม

เริ่มคิดต้นทุนตั้งแต่เริ่มต้น ทำไมต้องเป็นคอลเลกชัน? คำนี้มาจากสิ่งต่างๆ เช่น "ทฤษฎีประเภท" และ "ประเภทข้อมูลนามธรรม" แต่ถ้าคุณไม่มองเรื่องสูงๆ เลย เมื่อเรามีหลายสิ่งก็เรียกได้ว่าเป็น “ของสะสม” พวกที่สะสมของ. โดยทั่วไปคำว่า collect มาจากภาษาละติน collectio "การรวบรวมการรวบรวม" นั่นคือคอลเลกชั่นคือคอลเลกชั่นของบางสิ่งบางอย่าง ซึ่งเป็นคอนเทนเนอร์สำหรับองค์ประกอบบางอย่าง ดังนั้นเราจึงมีองค์ประกอบต่างๆ เราอาจต้องการทำอะไรกับมัน:
สั้น ๆ เกี่ยวกับสิ่งสำคัญ - Java Collections Framework - 3
อย่างที่คุณเห็น เราอาจต้องการสิ่งที่ค่อนข้างสมเหตุสมผล เรายังเข้าใจด้วยว่าเราอาจต้องการทำอะไรบางอย่างกับหลายคอลเลกชัน:
สั้น ๆ เกี่ยวกับสิ่งสำคัญ - Java Collections Framework - 4
ดังนั้น นักพัฒนา Java จึงเขียนอินเท อ ร์เฟซ java.util.Collectionเพื่ออธิบายลักษณะการทำงานทั่วไปนี้สำหรับคอลเลกชันทั้งหมด อินเทอร์เฟซคอลเลกชันเป็นที่ที่คอลเลกชันทั้งหมดเกิดขึ้น คอลเลกชันคือแนวคิด มันเป็นแนวคิดว่าคอลเลกชันทั้งหมดควรประพฤติตนอย่างไร ดังนั้นคำว่า "คอลเลกชัน" จึงแสดงเป็นอินเทอร์เฟซ แน่นอนว่าอินเทอร์เฟซจำเป็นต้องมีการใช้งาน อินเทอร์เฟjava.util.CollectionซมีคลาสนามธรรมAbstractCollectionนั่นคือ "คอลเลกชันนามธรรม" บางส่วน ซึ่งแสดงถึงโครงกระดูกสำหรับการใช้งานอื่นๆ (ตามที่เขียนใน JavaDoc เหนือคลาสjava.util.AbstractCollection) เมื่อพูดถึงคอลเลกชั่น เราย้อนกลับไปและจำไว้ว่าเราต้องการจะย้ำคอลเลกชั่นเหล่านั้น ซึ่งหมายความว่าเราต้องการวนซ้ำองค์ประกอบต่างๆ ทีละรายการ นี่เป็นแนวคิดที่สำคัญมาก ดังนั้นอินเทอร์เฟซCollectionจึงสืบทอดมาจากIterable. สิ่งนี้สำคัญมากเพราะว่า... ประการแรก ทุกสิ่งที่ Iterable จะต้องสามารถส่งคืน Iterator ตามเนื้อหาได้ และประการที่สอง ทุกอย่างที่ Iterable สามารถนำไปใช้ในลูปfor-each-loopได้ และด้วยความช่วยเหลือของตัววนซ้ำ ที่จะ นำวิธีAbstractCollectionการต่างๆ เช่นcontains, มาใช้ และเส้นทางสู่การทำความเข้าใจคอลเลกชันเริ่มต้นด้วยหนึ่งในโครงสร้างข้อมูลที่พบบ่อยที่สุด - รายการเช่น . toArrayremoveList
สั้น ๆ เกี่ยวกับสิ่งสำคัญ - Java Collections Framework - 5

รายการ

ดังนั้นรายการจึงมีความสำคัญในลำดับชั้นของคอลเลกชัน:
สั้น ๆ เกี่ยวกับสิ่งสำคัญ - Java Collections Framework - 6
ดังที่เราเห็น รายการใช้ อินเท อ ร์เฟซ java.util.List รายการแสดงว่าเรามีคอลเลกชันขององค์ประกอบที่จัดเรียงตามลำดับบางอย่าง แต่ละองค์ประกอบมีดัชนี (เหมือนในอาร์เรย์) โดยปกติแล้ว รายการจะทำให้คุณมีองค์ประกอบที่มีค่าเท่ากันได้ ดังที่เราได้กล่าวไว้ข้างต้นListมันรู้เกี่ยวกับดัชนีขององค์ประกอบ สิ่งนี้ช่วยให้คุณได้รับ ( get) องค์ประกอบตามดัชนีหรือตั้งค่าสำหรับดัชนีเฉพาะ ( set) วิธีการรวบรวมadd, ช่วย addAllให้removeคุณสามารถระบุดัชนีที่จะดำเนินการได้ นอกจากนี้ y Listยังมีตัววนซ้ำเวอร์ชันของตัวเองที่เรียกว่าListIterator. ตัววนซ้ำนี้รู้เกี่ยวกับดัชนีขององค์ประกอบ ดังนั้นจึงสามารถวนซ้ำได้ไม่เพียงแต่ไปข้างหน้าเท่านั้น แต่ยังย้อนกลับได้อีกด้วย สามารถสร้างได้จากสถานที่เฉพาะในคอลเลกชันด้วยซ้ำ ในบรรดาการใช้งานทั้งหมด มีสองประเภทที่ใช้บ่อยที่สุด: ArrayListและLinkedList. อันดับแรกArrayListคือรายการ ( List) ตามอาร์เรย์ ( Array) สิ่งนี้ช่วยให้คุณบรรลุ "การเข้าถึงแบบสุ่ม" ไปยังองค์ประกอบต่างๆ การเข้าถึงแบบสุ่มคือความสามารถในการดึงข้อมูลองค์ประกอบตามดัชนีทันที แทนที่จะวนซ้ำองค์ประกอบทั้งหมดจนกว่าเราจะพบองค์ประกอบที่มีดัชนีที่ต้องการ มันเป็นอาร์เรย์ที่เป็นพื้นฐานที่ช่วยให้บรรลุสิ่งนี้ได้ ในทางตรงกันข้ามLinkedListมันเป็นรายการที่เชื่อมโยง แต่ละรายการในรายการที่เชื่อมโยงจะแสดงในรูปแบบEntryซึ่งจัดเก็บข้อมูลเอง เช่นเดียวกับลิงก์ไปยังรายการถัดไป (ถัดไป) และก่อนหน้า (ก่อนหน้าEntry) จึง ใช้ " LinkedListSequential Access " เป็นที่ชัดเจนว่าในการหาองค์ประกอบที่ 5 เราจะต้องไปจากองค์ประกอบแรกไปยังองค์ประกอบสุดท้ายเพราะว่า เราไม่สามารถเข้าถึงองค์ประกอบที่ห้าได้โดยตรง เราสามารถเข้าถึงได้จากองค์ประกอบที่ 4 เท่านั้น ความแตกต่างในแนวคิดมีดังต่อไปนี้:
สั้น ๆ เกี่ยวกับสิ่งสำคัญ - Java Collections Framework - 7
ในการทำงานอย่างที่คุณเข้าใจก็มีความแตกต่างเช่นกัน เช่น การเพิ่มองค์ประกอบ องค์ประกอบLinkedListต่างๆ เชื่อมต่อกันเหมือนเป็นลิงก์ในลูกโซ่ แต่ArrayListจะเก็บองค์ประกอบไว้ในอาร์เรย์ และอย่างที่เรารู้กันว่าอาร์เรย์ไม่สามารถเปลี่ยนขนาดของมันได้ แล้วมันทำงานยังไงล่ะArrayList? และมันก็ใช้งานได้ง่ายมาก เมื่อพื้นที่ในอาเรย์หมด พื้นที่จะเพิ่มขึ้น 1.5 เท่า นี่คือรหัสการซูม: int newCapacity = oldCapacity + (oldCapacity >> 1); ความแตกต่างในการทำงานอีกประการหนึ่งคือการแทนที่องค์ประกอบต่างๆ เช่นเมื่อเพิ่มหรือลบองค์ประกอบที่อยู่ตรงกลาง หากต้องการลบออกจากLinkedListองค์ประกอบ เพียงลบการอ้างอิงไปยังองค์ประกอบนี้ ในกรณีของเราArrayListถูกบังคับให้เปลี่ยนองค์ประกอบในแต่ละครั้งโดยใช้ System.arraycopyดังนั้นยิ่งมีองค์ประกอบมากเท่าไรก็ยิ่งต้องดำเนินการมากขึ้นเท่านั้น คำอธิบายโดยละเอียดเพิ่มเติมสามารถพบได้ในบทความเหล่านี้: เมื่อตรวจสอบ ArrayList แล้ว ก็อดไม่ได้ที่จะจำคลาสjava.util.Vector ซึ่งเป็นคลาส "รุ่นก่อน" ได้ มันแตกต่างตรงVectorที่ArrayListวิธีการทำงานกับคอลเลกชัน (การเพิ่ม, การลบ, ฯลฯ ) จะถูกซิงโครไนซ์ นั่นคือ หากเธรดหนึ่ง ( Thread) เพิ่มองค์ประกอบ เธรดอื่นๆ จะรอจนกว่าเธรดแรกจะทำงานเสร็จ เนื่องจากมักไม่ต้องการความปลอดภัยของเธรด จึงแนะนำให้ใช้คลาสในกรณีดังกล่าว ดังที่ระบุไว้อย่างชัดเจนใน JavaDoc สำหรับArrayListคลาส Vectorนอกจากนี้Vectorยังเพิ่มขนาดไม่ 1.5 เท่าArrayListแต่เพิ่มขึ้น 2 เท่า มิฉะนั้นพฤติกรรมจะเหมือนกัน - Vectorการจัดเก็บองค์ประกอบในรูปแบบของอาร์เรย์จะถูกซ่อนไว้ และการเพิ่ม/ลบองค์ประกอบจะมีผลเช่นเดียวกับArrayListใน อันที่จริงVectorเราจำสิ่งนี้ได้ด้วยเหตุผล หากเราดูใน Javadoc เราจะเห็นโครงสร้างเช่นjava.util.Stack ใน "Direct Known Subclasses " Stack เป็นโครงสร้างที่น่าสนใจที่เป็นlast-in-first-outโครงสร้าง LIFO (เข้าหลังออกก่อน) Stack ที่แปลจากภาษาอังกฤษคือ Stack (เช่น กองหนังสือ เป็นต้น) สแต็กใช้วิธีการเพิ่มเติม: peek(look, look), pop(push), push(push) วิธีการนี้peekแปลได้ว่า look (เช่นมองเข้าไปในกระเป๋าแปลว่า “ มองเข้าไปในกระเป๋า ” และการมองผ่านรูกุญแจแปลว่า “ มองผ่านรูกุญแจ ”) วิธีนี้ช่วยให้คุณดูที่ "ด้านบน" ของสแต็กได้ เช่น รับองค์ประกอบสุดท้ายโดยไม่ต้องลบ (เช่นโดยไม่ต้องลบ) ออกจากสแต็ก วิธีการpushผลัก (เพิ่ม) องค์ประกอบใหม่ลงบนสแต็กและส่งกลับ และวิธีการองค์ประกอบpopจะผลัก (ลบ) และส่งคืนองค์ประกอบที่ถูกลบออก ในทั้งสามกรณี (เช่น peek, pop และ push) เราจะทำงานกับองค์ประกอบสุดท้ายเท่านั้น (เช่น "ด้านบนของสแต็ก") นี่คือคุณสมบัติหลักของโครงสร้างสแต็ก อย่างไรก็ตาม มีงานที่น่าสนใจในการทำความเข้าใจสแต็กตามที่อธิบายไว้ในหนังสือ “A Programmer's Career” (Cracking Coding Interview) มีงานที่น่าสนใจที่ต้องใช้โครงสร้าง “สแต็ก” (LIFO) คุณต้องใช้ “คิว” ” โครงสร้าง (FIFO) มันควรมีลักษณะเช่นนี้:
สั้น ๆ เกี่ยวกับสิ่งสำคัญ - Java Collections Framework - 8
การวิเคราะห์งานนี้สามารถพบได้ที่นี่: " ใช้งานคิวโดยใช้สแต็ก - The Queue ADT ("ใช้งานคิวโดยใช้สแต็ค" บน LeetCode) " ดังนั้นเราจึงย้ายไปยังโครงสร้างข้อมูลใหม่อย่างราบรื่น - คิว
สั้น ๆ เกี่ยวกับสิ่งสำคัญ - Java Collections Framework - 9

คิว

คิวเป็นโครงสร้างที่เราคุ้นเคยมาตลอดชีวิต ต่อคิวไปร้านค้าไปหาหมอ ใครมาก่อน (First In) จะเป็นคนแรกที่ออกจากคิว (First Out) ใน Java คิวจะถูกแสดงโดย อินเตอร์เฟส java.util.Queue ตาม Javadoc ของคิว คิวจะเพิ่มเมธอดต่อไปนี้:
สั้น ๆ เกี่ยวกับสิ่งสำคัญ - Java Collections Framework - 10
อย่างที่คุณเห็นมีวิธีการสั่งซื้อ (ความล้มเหลวในการดำเนินการนั้นเต็มไปด้วยข้อยกเว้น) และมีวิธีคำขอ (การไม่สามารถดำเนินการได้ไม่ทำให้เกิดข้อผิดพลาด) นอกจากนี้ยังสามารถรับองค์ประกอบได้โดยไม่ต้องลบออก (ดูหรือองค์ประกอบ) อิน เทอร์เฟซคิวยังมีตัวตายตัวแทนที่มีประโยชน์ - Deque นี่คือสิ่งที่เรียกว่า "คิวสองทาง" นั่นคือคิวดังกล่าวช่วยให้คุณใช้โครงสร้างนี้ทั้งจากจุดเริ่มต้นและจุดสิ้นสุด เอกสารระบุว่า "Deques ยังสามารถใช้เป็นสแต็ก LIFO (เข้าก่อน-ออกก่อน) ได้ อินเทอร์เฟซนี้ควรใช้ในการตั้งค่าตามความชอบของคลาส Stack ดั้งเดิม" นั่นคือ ขอแนะนำให้ใช้การใช้งาน Deque แทน ซ้อนกัน. Javadoc แสดงวิธีการที่อินเทอร์เฟซ Deque อธิบาย:
สั้น ๆ เกี่ยวกับสิ่งสำคัญ - Java Collections Framework - 11
มาดูกันว่ามีการใช้งานอะไรบ้าง และเรา จะเห็นข้อเท็จจริงที่น่าสนใจ - LinkedList ได้เข้าสู่ค่ายคิวแล้ว) นั่นคือ LinkedList ดำเนินการทั้งListและ Dequeแต่ก็มี “คิวเท่านั้น” เช่นกันPriorityQueueเช่น เธอไม่ได้ถูกจดจำบ่อยนัก แต่ไร้ประโยชน์ ประการแรก คุณไม่สามารถใช้ "วัตถุที่ไม่สามารถเปรียบเทียบได้" ในคิวนี้ได้ เช่น ต้องระบุตัวเปรียบเทียบอย่างใดอย่างหนึ่งหรือวัตถุทั้งหมดจะต้องเปรียบเทียบได้ ประการที่สอง "การใช้งานนี้ให้เวลา O(log(n)) สำหรับวิธีการจัดคิวและการจัดคิว" ความซับซ้อนของลอการิทึมมีเหตุผลอยู่ ใช้งาน PriorityQueue ตามฮีป Javadoc กล่าวว่า: "คิวลำดับความสำคัญแสดงเป็นฮีปไบนารีที่สมดุล" ที่เก็บข้อมูลสำหรับสิ่งนี้คืออาเรย์ปกติ ซึ่งเติบโตเมื่อมีความจำเป็น เมื่อฮีปมีขนาดเล็กก็จะเพิ่มขึ้น 2 เท่า แล้วอีก 50% ความคิดเห็นจากรหัส: "เพิ่มเป็นสองเท่าหากเล็ก มิฉะนั้นจะเติบโต 50%" คิวลำดับความสำคัญและ Binary Heap เป็นหัวข้อที่แยกจากกัน หากต้องการข้อมูลเพิ่มเติม: การใช้งานอาจjava.util.Dequeเป็น คลาส java.util.ArrayDeque นั่นคือ รายการสามารถนำไปใช้ได้โดยใช้รายการที่เชื่อมโยงและอาร์เรย์ และคิวยังสามารถนำไปใช้ได้โดยใช้อาร์เรย์หรือใช้รายการที่เชื่อมโยง Queueและอินเทอร์เฟซ มีการสืบทอดที่แสดง ถึงDeque"คิวการบล็อก": BlockingQueueและ BlockingDequeนี่คือการเปลี่ยนแปลงอินเทอร์เฟซเมื่อเทียบกับคิวปกติ:
สั้น ๆ เกี่ยวกับสิ่งสำคัญ - Java Collections Framework - 12
มาดูตัวอย่างการบล็อกคิวกัน แต่พวกเขามีความน่าสนใจ ตัวอย่างเช่น BlockingQueue ถูกนำมาใช้โดย: PriorityBlockingQueue , SynchronousQueue , ArrayBlockingQueue , DelayQueue , LinkedBlockingQueue แต่ พวกเขาใช้ทุกอย่างจาก Collection Frameworks BlockingDequeมาตรฐาน LinkedBlockingDequeแต่ละคิวเป็นหัวข้อรีวิวแยกกัน และภายในกรอบของการทบทวนนี้ เราจะพรรณนาถึงลำดับชั้นของคลาสไม่เพียงแต่ด้วยListแต่ยังรวมถึงQueue:
สั้น ๆ เกี่ยวกับสิ่งสำคัญ - Java Collections Framework - 13
ดังที่เราเห็นจากแผนภาพ อินเทอร์เฟซและคลาสของ Java Collections Framework มีความเชื่อมโยงกันอย่างมาก มาเพิ่มอีกสาขาหนึ่งของลำดับชั้น - Set.
สั้น ๆ เกี่ยวกับสิ่งสำคัญ - Java Collections Framework - 14

ชุด

Set— แปลว่า “ชุด” มันแตกต่าง จากคิวและรายการSetในแง่นามธรรมมากกว่าการจัดเก็บองค์ประกอบ Set- เหมือนถุงใส่สิ่งของ โดยไม่รู้ว่าวัตถุนั้นตั้งอยู่อย่างไร และวางอยู่ในลำดับใด ใน Java ชุดดังกล่าวจะแสดงโดย อินเท อ ร์เฟ ซ java.util.Set ตามที่เอกสารระบุไว้Setนี่คือ "คอลเลกชันที่ไม่มีองค์ประกอบที่ซ้ำกัน" ที่น่าสนใจคืออินเทอร์เฟซนั้นSetไม่ได้เพิ่มวิธีการใหม่ให้กับอินเทอร์เฟซCollectionแต่เพียงชี้แจงข้อกำหนดเท่านั้น (เกี่ยวกับสิ่งที่ไม่ควรมีรายการที่ซ้ำกัน) นอกจากนี้ จากคำอธิบายก่อนหน้านี้ ระบุว่าคุณไม่สามารถSetรับองค์ประกอบจากองค์ประกอบนั้น ได้ Iterator ใช้เพื่อรับองค์ประกอบ Setมีอินเทอร์เฟซเพิ่มเติมอีกหลายรายการที่เกี่ยวข้องกัน อันแรกก็คือSortedSet. ตามชื่อที่แนะนำSortedSetบ่งชี้ว่าชุดดังกล่าวถูกจัดเรียง ดังนั้นองค์ประกอบจึงใช้อินเทอร์เฟซหรือComparableระบุ Comparatorนอกจากนี้ยังSortedSetมีวิธีการที่น่าสนใจหลายประการ:
สั้น ๆ เกี่ยวกับสิ่งสำคัญ - Java Collections Framework - 15
นอกจากนี้ยังมีวิธีการfirst(องค์ประกอบที่เล็กที่สุดตามค่า) และlast(องค์ประกอบที่ใหญ่ที่สุดตามค่า) มีSortedSetทายาท - NavigableSet. วัตถุประสงค์ของอินเทอร์เฟซนี้คือการอธิบายวิธีการนำทางที่จำเป็นเพื่อระบุองค์ประกอบที่เหมาะสมได้แม่นยำยิ่งขึ้น สิ่งที่น่าสนใจคือNavigableSetมันเพิ่มตัววนซ้ำตามปกติ (ซึ่งเปลี่ยนจากเล็กที่สุดไปใหญ่ที่สุด) ตัววนซ้ำสำหรับลำดับย้อนกลับ descendingIterator- นอกจากนี้ยังNavigableSetช่วยให้คุณใช้วิธีdescendingSetรับมุมมองของตัวเอง (View) ซึ่งองค์ประกอบต่างๆ อยู่ในลำดับย้อนกลับ สิ่งนี้ถูกเรียกViewเพราะว่าคุณสามารถเปลี่ยนองค์ประกอบขององค์ประกอบดั้งเดิมผ่านองค์ประกอบผลลัพธ์Setได้ โดยพื้นฐานแล้วมันคือการนำเสนอข้อมูลต้นฉบับในรูปแบบที่แตกต่างออกไป ไม่ใช่สำเนาของข้อมูลดังกล่าว สิ่งที่น่าสนใจNavigableSetเช่นQueueสามารถจัดการองค์ประกอบpollFirst(น้อยที่สุด) และ (สูงสุด) ได้ pollLastนั่นคือได้รับองค์ประกอบนี้และลบออกจากชุด มีการใช้งานประเภทใดบ้าง? ประการแรก การใช้งานที่มีชื่อเสียงที่สุดนั้นใช้รหัสแฮช - HashSet การใช้งานที่รู้จักกันดีไม่แพ้กันอีกอย่าง หนึ่งนั้นใช้ต้นไม้สีแดงดำ - TreeSet มาทำแผนภาพของเราให้สมบูรณ์:
สั้น ๆ เกี่ยวกับสิ่งสำคัญ - Java Collections Framework - 16
ภายในคอลเลกชันยังคงต้องแยกแยะลำดับชั้น - ฤาษี ซึ่งเมื่อมองแวบแรกก็ยืนเคียงข้างกัน - java.util.Map.
สั้น ๆ เกี่ยวกับสิ่งสำคัญ - Java Collections Framework - 17

แผนที่

แผนที่เป็นโครงสร้างข้อมูลที่จัดเก็บข้อมูลด้วยคีย์ ตัวอย่างเช่น กุญแจอาจเป็นรหัสหรือรหัสเมือง และด้วยคีย์นี้เองที่ข้อมูลจะถูกค้นหา ที่น่าสนใจคือการ์ดจะแสดงแยกกัน ตามที่นักพัฒนา (ดู " คำถามที่พบบ่อยเกี่ยวกับการออกแบบ Java Collections API ") การแมปคีย์-ค่าไม่ใช่คอลเลกชัน และแผนที่สามารถถูกมองว่าเป็นชุดของคีย์ ชุดของค่า ชุดของคู่ของคีย์-ค่าได้รวดเร็วยิ่งขึ้น นี่เป็นสัตว์ที่น่าสนใจมาก การ์ดมีวิธีการใดบ้าง? ลองดูที่อินเทอร์เฟซ Java API java.util.Map เพราะ เนื่องจากแผนที่ไม่ใช่คอลเล็กชัน (ไม่ได้รับการสืบทอดจากคอลเล็กชัน) จึงไม่มีไฟล์contains. และนี่คือตรรกะ แผนที่ประกอบด้วยคีย์และค่า วิธีใดต่อไปนี้ควรตรวจสอบcontainsและทำอย่างไรไม่ให้สับสน? ดังนั้นอินเทอร์เฟซจึงMapมีสองเวอร์ชันที่แตกต่างกัน: containsKey(ประกอบด้วยคีย์) และcontainsValue(ประกอบด้วยค่า) การใช้มันkeySetช่วยให้คุณได้รับชุดกุญแจ (อันเดียวกันSet) และการใช้วิธีการนี้valuesทำให้เราสามารถรวบรวมค่าต่างๆ ในแผนที่ได้ ปุ่มต่างๆ ในแผนที่มีเอกลักษณ์เฉพาะตัว ซึ่งเน้นที่โครงสร้างSetข้อมูล สามารถทำซ้ำค่าได้ซึ่งเน้นโดยโครงสร้างข้อมูล Collection นอกจากนี้ เมื่อใช้วิธีนี้entrySetเราสามารถรับชุดคู่คีย์-ค่าได้ คุณสามารถอ่านเพิ่มเติมเกี่ยวกับการใช้งานการ์ดได้ในการวิเคราะห์โดยละเอียดที่สุด: ฉันยังต้องการที่จะเห็นสิ่งที่คล้ายHashMapกับHashSetและTreeMapถึง TreeSetพวกเขายังมีอินเทอร์เฟซที่คล้ายกัน: NavigableSetทั้งNavigableMapสองSortedSetและSortedMap. ดังนั้นแผนที่สุดท้ายของเราจะมีลักษณะดังนี้:
สั้น ๆ เกี่ยวกับสิ่งสำคัญ - Java Collections Framework - 18
เราขอจบด้วยข้อเท็จจริงที่น่าสนใจที่คอลเลกชันSetใช้ภายในMapโดยที่ค่าที่เพิ่มคือคีย์ และค่าจะเหมือนกันทุกที่ สิ่งนี้น่าสนใจเพราะMapไม่ใช่การรวบรวมและการคืนสินค้าSetซึ่งเป็นการรวบรวม แต่ในความเป็นจริงแล้วถูกนำไปใช้Mapเป็น เหนือจริงเล็กน้อย แต่นั่นคือสิ่งที่เกิดขึ้น)
สั้น ๆ เกี่ยวกับสิ่งสำคัญ - Java Collections Framework - 19

บทสรุป

ข่าวดีก็คือว่าการรีวิวนี้สิ้นสุดที่นี่ ข่าวร้ายก็คือว่านี่เป็นบทความที่มีการวิจารณ์มาก การใช้งานแต่ละคอลเลกชันควรได้รับบทความแยกต่างหาก และสำหรับแต่ละอัลกอริทึมที่ซ่อนอยู่จากสายตาของเรา แต่จุดประสงค์ของการตรวจสอบนี้คือเพื่อจดจำว่ามันคืออะไรและมีความเชื่อมโยงระหว่างอินเทอร์เฟซอย่างไร ฉันหวังว่าหลังจากอ่านอย่างถี่ถ้วนแล้ว คุณจะสามารถวาดไดอะแกรมของคอลเลกชันจากหน่วยความจำได้ ตามปกติแล้วบางลิงค์: #เวียเชสลาฟ
ความคิดเห็น
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION