JavaRush /จาวาบล็อก /Random-TH /HashMap ใน Java - แผนที่ประเภทใด

HashMap ใน Java - แผนที่ประเภทใด

เผยแพร่ในกลุ่ม
สวัสดี! วันนี้เราจะพูดถึงโครงสร้างข้อมูลอื่น - แผนที่ ชื่ออย่างเป็นทางการของรัสเซียคือ "อาเรย์แบบเชื่อมโยง" แต่ไม่ได้ใช้บ่อยนัก ตัวเลือกทั่วไปคือ "พจนานุกรม", "แผนที่" หรือ (บ่อยที่สุด) ภาษาอังกฤษแบบสแลง "แผนที่" :) ภายในแผนที่ข้อมูลจะถูกจัดเก็บในรูปแบบ "คีย์" - "ค่า" นั่นคือเป็นคู่ ทั้งคีย์และค่าสามารถเป็นอ็อบเจ็กต์ใดก็ได้ เช่น ตัวเลข สตริง หรืออ็อบเจ็กต์ของคลาสอื่น

Map แตกต่างจากโครงสร้างข้อมูลอื่นๆ อย่างไร

ก่อนหน้านี้ เราพิจารณาโครงสร้างข้อมูลที่องค์ประกอบต่างๆ ถูกจัดเก็บด้วยตัวเอง ในอาร์เรย์หรือArrayList / LinkedListเราจัดเก็บองค์ประกอบจำนวนหนึ่ง แต่จะเกิดอะไรขึ้นถ้างานของเราเปลี่ยนแปลงเล็กน้อย? ตัวอย่างเช่น ลองนึกภาพว่าเรากำลังเผชิญกับภารกิจสร้างรายชื่อ 100 คน โดยจะเก็บชื่อนามสกุลและหมายเลขหนังสือเดินทางของบุคคลนั้นไว้ โดยหลักการแล้วมันไม่ยากขนาดนั้น ตัวอย่างเช่น คุณสามารถใส่ทั้งสองบรรทัดและสร้างรายการบรรทัดได้ดังนี้: “Anna Ivanovna Reshetnikova, 4211 717171” แต่โซลูชันนี้มีข้อเสียสองประการ ขั้นแรกเราอาจต้องมีฟังก์ชั่นค้นหาหนังสือเดินทาง และด้วยรูปแบบการจัดเก็บข้อมูลแบบนี้ก็จะเกิดปัญหา และประการที่สอง ไม่มีอะไรจะขัดขวางเราจากการสร้างคนสองคนที่มีหมายเลขหนังสือเดินทางเดียวกันได้ และนี่คือข้อเสียเปรียบที่ร้ายแรงที่สุดในการแก้ปัญหาของเรา สถานการณ์ดังกล่าวควรได้รับการยกเว้นโดยสิ้นเชิงไม่มีบุคคลสองคนที่มีหมายเลขหนังสือเดินทางเดียวกัน แผนที่ที่นี่และคุณสมบัติที่ประกาศมาเพื่อช่วยเหลือเรา (การจัดเก็บข้อมูลเป็นคู่ในรูปแบบ "คีย์" - "ค่า") มาดูการใช้งานแผนที่ที่พบบ่อยที่สุด - คลาสJava HashMapHashMap - นี่คือแผนที่ประเภทใด  - 1

การสร้าง HashMap ใน Java และทำงานกับชั้นเรียน

การใช้งานนี้สร้างได้ง่ายมาก:
public static void main(String[] args) {

   HashMap<Integer, String> passportsAndNames = new HashMap<>();

}
ที่นี่เราได้สร้างพจนานุกรมซึ่งองค์ประกอบต่างๆ จะถูกจัดเก็บในรูปแบบ "สตริงตัวเลข" ตัวเลขจะเป็นคีย์ และสตริงจะเป็นค่า นอกจากนี้เรายังระบุด้วยว่าเราจะมีคีย์ประเภทใด ( Integer) และเราจะมีค่าประเภทใด ( String) ทำไมจึงเป็นเช่นนี้? ประการแรกคีย์ใน HashMap จะไม่ซ้ำกันเสมอ วิธีนี้จะได้ผลดีสำหรับเราเพราะเราสามารถใช้หมายเลขหนังสือเดินทางเป็นกุญแจและหลีกเลี่ยงการซ้ำกัน และบรรทัดที่มีชื่อเต็มจะทำหน้าที่เป็นค่า (ชื่อเต็มของบุคคลต่างๆ สามารถเรียกซ้ำได้ง่าย ไม่มีอะไรผิดปกติสำหรับเรา)

การเพิ่มคู่ใหม่ให้กับ HashMap

งานนี้มีลักษณะดังนี้:
public class Main {

   public static void main(String[] args) {
       HashMap<Integer, String> passportsAndNames = new HashMap<>();


       passportsAndNames.put(212133, "Lydia Arkadievna Bublikova");
       passportsAndNames.put(162348, "Ivan Mikhailovich Serebryakov");
       passportsAndNames.put(8082771, "Donald John Trump");
       System.out.println(passportsAndNames);

   }

}
วิธีนี้ใช้สำหรับสิ่งput()นี้ นอกจากนี้ HashMap ยังมีวิธีการแทนที่toString()เพื่อให้สามารถพิมพ์ไปยังคอนโซลได้ ผลลัพธ์จะมีลักษณะดังนี้: {212133=Lidiya Arkadyevna Bublikova, 8082771=Donald John Trump, 162348=Ivan Mikhailovich Serebryakov}

คุณสมบัติของคีย์ HashMap

ทีนี้มาดูกันว่ากุญแจนั้นมีเอกลักษณ์เฉพาะตัวจริง ๆ หรือไม่? เรามาลองเพิ่มองค์ประกอบใหม่ด้วย คีย์ที่มีอยู่ ในแผนที่ แล้ว :
public static void main(String[] args) {

   HashMap<Integer, String> passportsAndNames = new HashMap<>();

   passportsAndNames.put(212133, "Lydia Arkadievna Bublikova");
   passportsAndNames.put(162348, "Ivan Mikhailovich Serebryakov");
   passportsAndNames.put(8082771, "Donald John Trump");
   passportsAndNames.put(162348, "Viktor Mikhailovich Stychkin");//repeat key

   System.out.println(passportsAndNames);

}
ผลลัพธ์: {212133=Lidiya Arkadyevna Bublikova, 8082771=Donald John Trump, 162348=Viktor Mikhailovich Stychkin} องค์ประกอบก่อนหน้าที่มีคีย์ 162348 อย่างที่คุณเห็น ถูกเขียนทับ “กุญแจ” ถูกเรียกว่ากุญแจด้วยเหตุผล ค่าใน HashMap เข้าถึงได้ด้วยคีย์ (แต่ไม่ใช่ในทางกลับกัน - ไม่สามารถรับคีย์ได้ด้วยค่าเนื่องจากค่าสามารถทำซ้ำได้) สิ่งนี้เห็นได้ชัดเจนในตัวอย่างของการรับองค์ประกอบ เช่นเดียวกับการลบองค์ประกอบออกจาก HashMap:
public static void main(String[] args) {

   HashMap<Integer, String> passportsAndNames = new HashMap<>();

   passportsAndNames.put(212133, "Lydia Arkadievna Bublikova");
   passportsAndNames.put(162348, "Ivan Mikhailovich Serebryakov");
   passportsAndNames.put(8082771, "Donald John Trump");

   String lidiaName = passportsAndNames.get(212133);
   System.out.println(lidiaName);


   passportsAndNames.remove(162348);
   System.out.println(passportsAndNames);

}
ในการรับค่าหรือลบคู่ออกจากพจนานุกรม เราต้องส่งคีย์เฉพาะที่สอดคล้องกับค่านี้ ไปยัง get()เมธอด ไม่มีดัชนีตัวเลขเช่นเดียวกับในอาร์เรย์หรือรายการใน HashMap - ค่าเข้าถึงได้โดยใช้คีย์ เอาต์พุตคอนโซล: Lidiya Arkadyevna Bublikova {212133=Lidiya Arkadyevna Bublikova, 8082771=Donald John Trump}remove()

การตรวจสอบการมีอยู่ของคีย์และค่า

ใน คลาส ArrayListและLinkedListเราสามารถตรวจสอบว่ารายการมีองค์ประกอบเฉพาะหรือไม่ HashMapยังช่วยให้คุณทำเช่นนี้ได้ และสำหรับทั้งสองส่วนของคู่: มันมีวิธีการcontainsKey()(ตรวจสอบการมีอยู่ของคีย์) และcontainsValue()(ตรวจสอบการมีอยู่ของค่า)
public static void main(String[] args) {

   HashMap<Integer, String> passportsAndNames = new HashMap<>();

   passportsAndNames.put(212133, "Lydia Arkadievna Bublikova");
   passportsAndNames.put(162348, "Ivan Mikhailovich Serebryakov");
   passportsAndNames.put(8082771, "Donald John Trump");


   System.out.println(passportsAndNames.containsKey(11111));
   System.out.println(passportsAndNames.containsValue("Donald John Trump"));

}
ผลลัพธ์: เท็จ จริง

รับรายการคีย์และค่าทั้งหมด

คุณสมบัติที่สะดวกสบายอีกประการหนึ่งของ HashMap ก็คือ คุณสามารถแยกรายการคีย์ทั้งหมดและค่าทั้งหมดออกจากกันได้ สำหรับสิ่งนี้ วิธีการkeySet()และ การใช้งาน values():
public class Main {

   public static void main(String[] args) {

       HashMap<Integer, String> passportsAndNames = new HashMap<>();

       passportsAndNames.put(212133, "Lydia Arkadievna Bublikova");
       passportsAndNames.put(162348, "Ivan Mikhailovich Serebryakov");
       passportsAndNames.put(8082771, "Donald John Trump");

       Set<Integer> keys = passportsAndNames.keySet();
       System.out.println("Keys: " + keys);

       ArrayList<String> values = new ArrayList<>(passportsAndNames.values());
       System.out.println("Values: " + values);

   }

}
กุญแจจะถูกดึงออกมาสู่Setคอลเลคชัน ลักษณะเฉพาะของมันคือไม่สามารถมีองค์ประกอบที่ซ้ำกัน ตอนนี้สิ่งสำคัญที่ต้องจำก็คือรายการคีย์ทั้งหมดสามารถนำออกจาก HashMap ไปยังคอลเลกชันแยกต่างหากได้ ในตัวอย่างนี้เราบันทึกค่าให้เป็นค่าArrayListปกติ เอาต์พุตคอนโซล: คีย์: [212133, 8082771, 162348] ค่า: [Lidiya Arkadyevna Bublikova, Donald John Trump, Ivan Mikhailovich Serebryakov] วิธีsize()การทำclear()สิ่งเดียวกันกับในโครงสร้างก่อนหน้านี้ที่เราดำเนินการ: อันแรกส่งคืนองค์ประกอบตัวเลข ในพจนานุกรมในขณะนั้น ส่วนอันที่สองจะลบองค์ประกอบทั้งหมด
public static void main(String[] args) {

   HashMap<Integer, String> passportsAndNames = new HashMap<>();

   passportsAndNames.put(212133, "Lydia Arkadievna Bublikova");
   passportsAndNames.put(162348, "Ivan Mikhailovich Serebryakov");
   passportsAndNames.put(8082771, "Donald John Trump");

   System.out.println(passportsAndNames.size());
   passportsAndNames.clear();
   System.out.println(passportsAndNames);

}
ผลลัพธ์: 3 {} เพื่อตรวจสอบว่า HashMap ของเรามีองค์ประกอบอย่างน้อยหนึ่งองค์ประกอบหรือไม่ เราสามารถใช้เมธอดisEmpty():
public static void main(String[] args) {

   HashMap<Integer, String> passportsAndNames = new HashMap<>();

   passportsAndNames.put(212133, "Lydia Arkadievna Bublikova");
   passportsAndNames.put(162348, "Ivan Mikhailovich Serebryakov");
   passportsAndNames.put(8082771, "Donald John Trump");

   if (!passportsAndNames.isEmpty()) {

       System.out.println(passportsAndNames);

   }

}
ผลลัพธ์: {212133=Lidiya Arkadyevna Bublikova, 8082771=Donald John Trump, 162348=Ivan Mikhailovich Serebryakov} ตอนนี้เราจะส่งออกไปยังคอนโซลหลังจากการตรวจสอบเบื้องต้นเท่านั้น :)

รวมสองแผนที่เป็นหนึ่งเดียว

จุดที่น่าสนใจอีกประการหนึ่งคือแผนที่สองแห่งสามารถรวมเป็นหนึ่งเดียวได้ มีวิธีสำหรับสิ่งputAll()นี้ เราเรียกมันว่าHashMap อันแรก ส่งผ่านอันที่สองเป็นอาร์กิวเมนต์ และองค์ประกอบจากอันที่สองจะถูกเพิ่มเข้าไปในอันแรก:
public static void main(String[] args) {

   HashMap<Integer, String> passportsAndNames = new HashMap<>();
   HashMap<Integer, String> passportsAndNames2 = new HashMap<>();

   passportsAndNames.put(212133, "Lydia Arkadievna Bublikova");
   passportsAndNames.put(162348, "Ivan Mikhailovich Serebryakov");
   passportsAndNames.put(8082771, "Donald John Trump");

   passportsAndNames2.put(917352, "Alexey Andreevich Ermakov");
   passportsAndNames2.put(925648, "Maxim Olegovich Arkharov");


   passportsAndNames.putAll(passportsAndNames2);
   System.out.println(passportsAndNames);

}
ผลลัพธ์: {917352=Alexey Andreevich Ermakov, 212133=Lidiya Arkadyevna Bublikova, 8082771=Donald John Trump, 925648= Maxim Olegovich Arkharov, 162348=Ivan Mikhailovich Serebryakov} องค์ประกอบทั้งหมดของPassportsAndNames2ถูกคัดลอกไปยังPassportsAndNames ตอนนี้เรามาดูตัวอย่างที่ซับซ้อนกว่านี้กัน กล่าวคือ วนซ้ำ HashMap แบบวนซ้ำ
for (Map.Entry entry: passportsAndNames.entrySet()) {

   System.out.println(entry);

}
อินเทอร์เฟMap.Entryซหมายถึงคู่คีย์-ค่าภายในพจนานุกรม วิธีการentrySet()ส่งคืนรายการคู่ทั้งหมดใน HashMap ของเรา (เนื่องจากแผนที่ของเราประกอบด้วยคู่รายการดังกล่าว เราจึงวนซ้ำคู่ และไม่แยกคีย์หรือค่า) สรุป: 212133=Lidiya Arkadyevna Bublikova 8082771=Donald John Trump 162348=Ivan Mikhailovich Serebryakov บันทึกบทความนี้สำหรับอนาคต: https://habr.com/ru/post/128017/ ตอนนี้ยังเร็วเกินไปที่จะอ่าน แต่ในอนาคต เมื่อคุณจะได้ลองใช้ HashMap มันจะช่วยให้คุณเข้าใจว่าโครงสร้างข้อมูลนี้ทำงานจากภายในอย่างไร นอกจากนี้ อย่าลืมตรวจสอบเอกสารอย่างเป็นทางการของOracleบน HashMap
ความคิดเห็น
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION