CodeGym /בלוג Java /Random-HE /HashMap: איזו מין מפה זו?
John Squirrels
רָמָה
San Francisco

HashMap: איזו מין מפה זו?

פורסם בקבוצה
היי! בשיעור זה, נסקור סקירה מעמיקה יותר ב- Java HashMap . בעבר, למדנו מבני נתונים שבהם האלמנטים מאוחסנים כעצמם. במערך או ב- ArrayList / LinkedList , אנו מאחסנים מספר מסוים של אלמנטים. אבל מה אם המשימה שלנו תשתנה מעט?
HashMap: איזו מין מפה זו?  - 1
דמיינו לעצמכם את המשימה הבאה: צרו רשימה של 100 אנשים המאחסנת את שמו ומספר הדרכון של כל אדם. באופן עקרוני, זה לא כל כך קשה. לדוגמה, אתה יכול להכניס את שניהם למחרוזת, ולאחר מכן ליצור רשימה של מחרוזות אלה: "אמיליה אגילר, 4211 717171". אבל לפתרון הזה יש שני חסרונות. ראשית, ייתכן שנצטרך את היכולת לחפש לפי מספר דרכון. וזה יהיה בעייתי בהתחשב בפורמט אחסון המידע הזה. שנית, שום דבר לא מונע מאיתנו ליצור שני אנשים שונים עם אותו מספר דרכון. וזה החיסרון החמור ביותר של הפתרון שלנו. לעולם אין לאפשר זאת: אין לשני אנשים אותו מספר דרכון. מבנה נתונים חדש בא לעזרתנו: מפה . הוא ידוע גם בתור "מערך אסוציאטיבי", אך מונח זה משמש לעתים רחוקות. באופן נפוץ יותר, זה נקרא "מילון" או "מפה". :) במה זה שונה מהותית ממבני הנתונים ששקלנו בעבר? מעל הכל, בעובדה שהנתונים במפה מאוחסנים כזוגות מפתח-ערך. כל דבר יכול לשמש כמפתחות וערכים: מספרים, מחרוזות או אובייקטים של מחלקות אחרות. היום נלמד את היישום הנפוץ ביותר של כיתת Map : Java HashMap . HashMap: איזו מין מפה זו?  - 2

אז מה אנחנו צריכים לדעת על HashMap ב-Java?

קל מאוד ליצור:
public static void main(String[] args) {
   HashMap<Integer, String> passportsAndNames = new HashMap<>();
}
כאן אנו יוצרים מילון המאחסן אלמנטים כזוגות "מחרוזת מספרים". המספר ישמש כמפתח, והמחרוזת כערך. כמו כן אנו מציינים את סוג המפתח (מספר שלם) ואת סוג הערך (מחרוזת). למה? ראשית, מפתח HashMap הוא תמיד ייחודי. זה מתאים לנו בצורה מושלמת, מכיוון שאנו יכולים להשתמש במספר הדרכון כמפתח ולהימנע מכפילויות. הערך יהיה מחרוזת עם השם המלא (לאנשים שונים יכולים להיות אותו שם; אין לנו מה לדאוג). הוספת זוג חדש ל- HashMap נראית כך:
public class Main {

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

       passportsAndNames.put (212133, "Bridget Logan");
       passportsAndNames.put (162348, "Ivan the Great");
       passportsAndNames.put(8082771, "Donald John Trump");
       System.out.println(passportsAndNames);
   }
}
אנחנו משתמשים בשיטה put() בשביל זה. בנוסף, HashMap עוקף את שיטת toString() כך שניתן להציג אותה במסוף. הפלט ייראה כך: {212133=Bridget Logan, 8082771=Donald John Trump, 162348=Ivan the Great} עכשיו בואו נוודא אם המפתחות באמת ייחודיים? בואו ננסה להוסיף אלמנט חדש עם מפתח שכבר נעשה בו שימוש במפה:
public static void main(String[] args) {
   HashMap<Integer, String> passportsAndNames = new HashMap<>();

   passportsAndNames.put (212133, "Bridget Logan");
   passportsAndNames.put (162348, "Ivan the Great");
   passportsAndNames.put(8082771, "Donald John Trump");
   passportsAndNames.put(162348, "Albert Kent");// This key has already been used
   System.out.println(passportsAndNames);
}
פלט: {212133=Bridget Logan, 8082771=Donald John Trump, 162348=Albert Kent} כפי שאתה יכול לראות, הערך הקודם המשויך למפתח 162348 הוחלף. אנו משתמשים במונח "מפתח" מסיבה מסוימת. ניתן לגשת לערכים ב- HashMap באמצעות המפתח, אך לא להיפך. לא ניתן להשיג את המפתח באמצעות ערך, שכן ייתכן שהערכים אינם ייחודיים. ניתן לראות זאת בבירור בעת קבלת או הסרה של רכיב מ- HashMap :
public static void main(String[] args) {
   HashMap<Integer, String> passportsAndNames = new HashMap<>();

   passportsAndNames.put (212133, "Bridget Logan");
   passportsAndNames.put (162348, "Ivan the Great");
   passportsAndNames.put(8082771, "Donald John Trump");

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

   passportsAndNames.remove(162348);
   System.out.println(passportsAndNames);
}
כדי לקבל ערך או להסיר זוג מהמילון, עלינו להעביר ל- get() ולהסיר () את המפתח הייחודי המתאים לערך. שלא כמו מערכים ורשימות, ל- HashMap ב-Java אין מדדים מספריים: הגישה לערכים מתבצעת באמצעות המפתח. פלט מסוף: Bridget Logan {212133=Bridget Logan, 8082771=Donald John Trump} המחלקות ArrayList ו- LinkedList מאפשרות לנו לבדוק אם הרשימה מכילה אלמנט מסוים. Java HashMap מאפשר לנו לעשות זאת. יתרה מכך, נוכל לעשות זאת עבור שני חברי הזוג: לשם כך מיועדות המתודות containsKey() (בודקת מפתח) ו- containsValue() (בודקת ערך).
public static void main(String[] args) {
   HashMap<Integer, String> passportsAndNames = new HashMap<>();

   passportsAndNames.put (212133, "Bridget Logan");
   passportsAndNames.put (162348, "Ivan the Great");
   passportsAndNames.put(8082771, "Donald John Trump");

   System.out.println(passportsAndNames.containsKey(11111));
   System.out.println(passportsAndNames.containsValue("Donald John Trump"));
}
פלט: false true תכונה נוחה נוספת של HashMap ב-Java היא העובדה שניתן לקבל רשימות נפרדות של כל המפתחות וכל הערכים. זה מושג עם השיטות keySet() ו- values() :
public class Main {

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

       passportsAndNames.put (212133, "Bridget Logan");
       passportsAndNames.put (162348, "Ivan the Great");
       passportsAndNames.put(8082771, "Donald John Trump");

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

       ArrayList<String> values = new ArrayList<>(passportsAndNames.values());
       System.out.println("Values: " + values);
   }
}
המפתחות נשלפים לתוך סט , שעדיין לא כיסינו. הוא מיוחד בכך שהוא אינו יכול להכיל אלמנטים חוזרים. כעת העיקר הוא לזכור שניתן לאחזר את רשימת כל המפתחות מ- HashMap לאוסף נפרד. בדוגמה, שמרנו את הערכים ב- ArrayList רגיל . פלט מסוף: מקשים: [212133, 8082771, 162348] ערכים: [ברידג'ט לוגן, דונלד ג'ון טראמפ, איוון הגדול] שיטות הגודל () וה- clear() עושות בדיוק את אותו הדבר כמו במבנים הקודמים שדנו בהם: הראשון מחזיר את מספר האלמנטים כרגע במילון, השני מסיר את כל האלמנטים.
public static void main(String[] args) {
   HashMap<Integer, String> passportsAndNames = new HashMap<>();

   passportsAndNames.put (212133, "Bridget Logan");
   passportsAndNames.put (162348, "Ivan the Great");
   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, "Bridget Logan");
   passportsAndNames.put (162348, "Ivan the Great");
   passportsAndNames.put(8082771, "Donald John Trump");

   if (!passportsAndNames.isEmpty()) {

       System.out.println(passportsAndNames);
   }
}
פלט: {212133=ברידג'ט לוגן, 8082771=דונלד ג'ון טראמפ, 162348=איבן הגדול} כעת נוציא למסוף רק לאחר בדיקה ראשונית. :) נקודה מעניינת נוספת היא שניתן לשלב שתי מפות לאחת. זה הושג באמצעות שיטת putAll() . אנו קוראים לזה ב- HashMap הראשון , מעבירים את השני כארגומנט, והאלמנטים מהשני מתווספים לראשון:
public static void main(String[] args) {
   HashMap<Integer, String> passportsAndNames = new HashMap<>();
   HashMap<Integer, String> passportsAndNames2 = new HashMap<>();

   passportsAndNames.put (212133, "Bridget Logan");
   passportsAndNames.put (162348, "Ivan the Great");
   passportsAndNames.put(8082771, "Donald John Trump");

   passportsAndNames2.put(917352, "Clifford Patrick");
   passportsAndNames2.put(925648, "Mitchell Salgado");

   passportsAndNames.putAll(passportsAndNames2);
   System.out.println(passportsAndNames);
}
פלט: {917352=קליפורד פטריק, 212133=ברידג'ט לוגן, 8082771=דונלד ג'ון טראמפ, 925648=מיטשל סלגאדו, 162348=איבן הגדול} כל הזוגות בדרכונים AndNames2 הועתקו לדרכונים AndNames . עכשיו שקול דוגמה מסובכת יותר. באופן ספציפי, איטרציה על HashMap בלולאה.
for (Map.Entry<Integer, String> entry: passportsAndNames.entrySet()) {
   System.out.println(entry);
}
המחלקה Map.Entry מציינת את צמד המפתח-ערך בתוך המילון. השיטה entrySet () מחזירה רשימה של כל הזוגות ב- HashMap שלנו . מכיוון שהמפה שלנו מורכבת מצמדי Map.Entry אלה , אנו חוזרים על זוגות, לא מפתחות או ערכים נפרדים. פלט: 212133=ברידג'ט לוגן 8082771=דונלד ג'ון טראמפ 162348=איבן הגדול כמו כן, אל תשכח ללמוד את התיעוד הרשמי של אורקל עבור HashMap .
הערות
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION