CodeGym /Java blog /Véletlen /HashMap: milyen térkép ez?
John Squirrels
Szint
San Francisco

HashMap: milyen térkép ez?

Megjelent a csoportban
Szia! Ebben a leckében közelebbről áttekintjük a Java HashMap szolgáltatást . Korábban olyan adatstruktúrákat tanulmányoztunk, amelyekben az elemek önmagukban vannak tárolva. Egy tömbben vagy egy ArrayList / LinkedList- ben bizonyos számú elemet tárolunk. De mi van, ha kicsit megváltozik a feladatunk?
HashMap: milyen térkép ez?  - 1
Képzelje el a következő feladatot: hozzon létre egy 100 fős listát, amely minden egyes személy nevét és útlevélszámát tárolja. Elvileg ez nem olyan nehéz. Például mindkettőt beleírhatja egy karakterláncba, majd létrehozhat egy listát ezekből a karakterláncokból: "Amelia Aguilar, 4211 717171". Ennek a megoldásnak azonban két hátránya is van. Először is szükségünk lehet az útlevélszám szerinti keresés lehetőségére. És ez problémás lesz az információ tárolási formátuma miatt. Másodszor, semmi sem akadályoz meg bennünket abban, hogy két különböző embert hozzunk létre azonos útlevélszámmal. És ez a megoldásunk legsúlyosabb hiányossága. Ezt soha nem szabad megengedni: nincs két embernek egyforma útlevélszáma. Egy új adatstruktúra jön a segítségünkre: Térkép. „asszociatív tömbként” is ismert, de ezt a kifejezést ritkán használják. Gyakrabban "szótárnak" vagy "térképnek" nevezik. :) Miben különbözik alapvetően az általunk korábban vizsgált adatstruktúráktól? Mindenekelőtt abban, hogy a térképen lévő adatok kulcs-érték párokként vannak tárolva. Kulcsként és értékként bármi szolgálhat: számok, karakterláncok vagy más osztályok objektumai. Ma a Map osztály leggyakoribb megvalósítását fogjuk tanulmányozni : Java HashMap . HashMap: milyen térkép ez?  - 2

Tehát mit kell tudnunk a Java HashMapről?

Nagyon egyszerű létrehozni:

public static void main(String[] args) {
   HashMap<Integer, String> passportsAndNames = new HashMap<>();
}
Itt létrehozunk egy szótárt, amely "szám-karakterlánc" párokként tárolja az elemeket. A szám kulcsként, a karakterlánc pedig értékként fog működni. Ezenkívül megadjuk a kulcstípust (Integer) és az érték típusát (String). Miért? Először is, a HashMap kulcs mindig egyedi. Ez nekünk tökéletesen megfelel, hiszen az útlevélszámot használhatjuk kulcsként és elkerülhetjük a duplikációkat. Az érték egy karakterlánc lesz a teljes névvel (különböző embereknek lehet ugyanaz a neve; emiatt nem kell aggódnunk). Egy új pár hozzáadása a HashMaphez így néz ki:

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);
   }
}
Ehhez a put() metódust használjuk . Ráadásul a HashMap felülírja a toString() metódust, így a konzolon is megjeleníthető. A kimenet így fog kinézni: {212133=Bridget Logan, 8082771=Donald John Trump, 162348=Nagy Iván} Most pedig ellenőrizzük, hogy a kulcsok valóban egyediek-e? Próbáljunk meg egy új elemet hozzáadni a térképen már használt kulccsal:

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);
}
Kimenet: {212133=Bridget Logan, 8082771=Donald John Trump, 162348=Albert Kent} Mint látható, az 162348 kulcshoz tartozó korábbi érték felül lett írva. A "kulcs" kifejezést okkal használjuk. A HashMap értékei a kulccsal érhetők el, de fordítva nem. A kulcs nem szerezhető be érték használatával, mivel az értékek nem feltétlenül egyediek. Ez jól látható, amikor egy elemet beszerez vagy eltávolít a HashMapről :

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);
}
Ahhoz, hogy értéket kapjunk, vagy eltávolítsunk egy párat a szótárból, át kell adnunk a get()- nek , és el kell távolítanunk () az értéknek megfelelő egyedi kulcsot. A tömbökkel és listákkal ellentétben a Java HashMap- nek nincsenek numerikus indexei: az értékek a kulccsal érhetők el. Konzol kimenet: Bridget Logan {212133=Bridget Logan, 8082771=Donald John Trump} Az ArrayList és LinkedList osztályok segítségével ellenőrizhetjük, hogy a lista tartalmaz-e valamilyen elemet. A Java HashMap lehetővé teszi ezt számunkra. Sőt, ezt megtehetjük a pár mindkét tagjával: Ez az, amit a includeKey() (kulcsot keres) és a includeValue()(értéket ellenőrzi) módszerek a.

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"));
}
Kimenet: false true A Java HashMap másik kényelmes tulajdonsága az a tény, hogy külön listát kaphat az összes kulcsról és értékről. Ez a keySet() és értékek() metódusokkal érhető el :

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);
   }
}
A kulcsok egy készletbe vannak kivonva , amivel még nem foglalkoztunk. Különlegessége, hogy nem tartalmazhat ismétlődő elemeket. Most a legfontosabb dolog az, hogy ne feledje, hogy az összes kulcs listája lekérhető a HashMapről egy külön gyűjteménybe. A példában az értékeket egy közönséges ArrayList- be mentettük . Konzol kimenet: Kulcsok: [212133, 8082771, 162348] Értékek: [Bridget Logan, Donald John Trump, Nagy Iván] A size() és clear() metódus pontosan ugyanazt teszi, mint a korábban tárgyalt struktúrákban: az első a szótárban lévő elemek számát adja vissza, a második eltávolítja az összes elemet.

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);
}
Kimenet: 3 {} Annak ellenőrzésére, hogy van-e legalább egy elem a HashMap- ünkben , használhatjuk az isEmpty() metódust:

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);
   }
}
Kimenet: {212133=Bridget Logan, 8082771=Donald John Trump, 162348=Nagy Iván} Most csak előzetes ellenőrzés után fogunk kimenni a konzolra. :) Egy másik érdekesség, hogy két Map-et lehet egyesíteni egybe. Ez a putAll() metódussal valósult meg. Meghívjuk az első HashMap- en , a másodikat argumentumként adjuk át, és a második elemei hozzáadódnak az elsőhöz:

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);
}
Kimenet: {917352=Clifford Patrick, 212133=Bridget Logan, 8082771=Donald John Trump, 925648=Mitchell Salgado, 162348=Nagy Iván} Az útlevelek és a nevek2 összes párja át lett másolva az útlevelekbe . Most vegyünk egy bonyolultabb példát. Pontosabban egy HashMap-en keresztüli iteráció ciklusban.

for (Map.Entry<Integer, String> entry: passportsAndNames.entrySet()) {
   System.out.println(entry);
}
A Map.Entry osztály a kulcs-érték párt jelöli a szótárban. Az enterSet() metódus a HashMap összes párjának listáját adja vissza . Mivel térképünk ezekből a Map.Entry párokból áll, párok között iterálunk, nem pedig külön kulcsokon vagy értékeken. Kimenet: 212133=Bridget Logan 8082771=Donald John Trump 162348=Nagy Iván Továbbá, ne felejtse el tanulmányozni a HashMap hivatalos Oracle dokumentációját .
Hozzászólások
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION