JavaRush /Java Blog /Random-TK /“HashMap” Java-da nähili işleýär

“HashMap” Java-da nähili işleýär

Toparda çap edildi
HashMapSöhbetdeşlikler wagtynda ara alyp maslahatlaşmak üçin şu gün iň halanýan mowzukdygyna köpüňiz razy bolarsyňyz . Käwagt kärdeşlerim bilen şuňa meňzeş pikir alyşýardym we bu hakykatdanam kömek etdi. Indi siziň bilen şeýle pikir alyşaryn. “HashMap” -yň içerki we işleýşi bilen gyzyklanýan bolsaňyz, “HashMap”“HashMap” -yň Java-da nähili işleýändigi - 1 -yň esaslary bilen eýýäm tanyşdygyňyzy çaklaýaryn , şonuň üçin bu bölümi taşlaryn. Thisöne bu meselede täze bolsaňyz, Java Docs sahypasyna girmegiňizi maslahat berýärin . Geçmezden ozal, öňki makalamy barlamagy maslahat berýärin: hashCode bilen işlemek we Java-da deň usul. Bu makalanyň mazmuny:
  1. Onlyeke-täk jogap.
  2. Haşing näme.
  3. Synp hakda azajyk Entry.
  4. Näme edýär put().
  5. Usulyň nähili işleýändigi get().
  6. Bellikler

Onlyeke-täk jogap

Kimdir biri " HashMap nähili işleýär?" Diýip düşündirmegimi haýyş etse. ", Diňe jogap bererin:" Haşing prinsiplerine görä . " Has ýönekeý bolup bilmez. Muňa düşünmek we giňişleýin jogap almak üçin Haşingiň esaslaryny bilýändigiňize göz ýetirmeli. Dogry?

Haşing näme

Iň ýönekeý görnüşinde ýuwmak, islendik formulany / algoritmi öz häsiýetlerine ulanandan soň islendik üýtgeýän / obýekti üýtgeşik koda öwürmegiň usulydyr. Hakyky hash funksiýasy aşakdaky düzgüne eýermelidir: Haş funksiýasy şol bir ýa-da deň obýektlere ulanylanda şol bir hash koduny yzyna gaýtarmalydyr. Başgaça aýdylanda, iki meňzeş obýekt öz gezeginde şol bir hash kodlaryny yzyna gaýtarmaly.
hashCode()Bellik: Java-daky ähli obýektler synpda beýan edilen funksiýanyň standart ýerine ýetirilişine miras galar Object. Bu funksiýa, obýektiň içerki salgysyny sana öwürmek arkaly alnan hash koduny yzyna gaýtaryp berýär, bu bolsa her bir obýekt üçin özboluşly kod döredilmegine sebäp bolýar.
Bu hakda has giňişleýin maglumaty şu ýerden okap bilersiňiz: hashCode bilen işlemek we Java-da deň usul

Giriş synpy barada azajyk

Kesgitleme boýunça, karta “gymmatlyklary we açarlary jübüt saklaýan obýektdir. Örän ýönekeý, şeýlemi? Şeýlelik bilen, “HashMap” -da jübüt gymmatlyklary we açarlary saklaýan haýsydyr bir mehanizm bolmalymy? Jogap - Hawa. meňzeş içki synpy HashMapbar :Entry
static class Entry implements Map.Entry
{
        final K key;
        V value;
        Entry next;
        final int hash;
        ...//остальной code тут…
}
Elbetde, synpda Entryatributlar hökmünde saklanýan açar we baha bar. Açar bellendi finalwe goşmaça iki meýdany hem görýäris: nextwe hash. Makalanyň dowamy bilen bu ugurlaryň maksadyna düşünmäge synanyşarys.

Java goýýan () usuly näme edýär?

Usulyň durmuşa geçirilişine göz aýlamazdan ozal synpyň mysallarynyň bir massiwde saklanýandygyna put()düşünmek gaty möhümdir . Entry“HashMap” synpy bu üýtgeýjini şeýle kesgitleýär:
/**
* Размер таблицы, изменяется при необходимости. Длина всегда должна быть
* кратна двум!
*/
    transient Entry[] table;
Indi usuly ýerine ýetiriş koduna göz aýlaň put():
/**
* Связывает определенное meaning с определенным ключом в этой карте(map).
* Если карта перед этим содержала meaning для данного ключа, это meaning
* заменится на новое.
*
* @param key
*            ключ с которым указанное meaning должно быть связано.
* @param value
*            meaning которое должно быть связано с ключом.
* @return вернет предыдущее meaning связанное с key, or null
*         если не было значений связанных с key. (Вернет null
*         так же, если перед этим key был связан со meaningм null)
*/
public V put(K key, V value) {
if (key == null)
return putForNullKey(value);
int hash = hash(key.hashCode());
int i = indexFor(hash, table.length);
for (Entry<k , V> e = table[i]; e != null; e = e.next) {
Object k;
if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
V oldValue = e.value;
e.value = value;
e.recordAccess(this);
return oldValue;
}
}

modCount++;
addEntry(hash, key, value, i);
return null;
}
Stepdim-ädim kesgitläliň:
  • Ilki bilen açaryň bardygyny ýa-da ýokdugyny barlaýarys. Eger açar ýok bolsa ( null), baha nol pozisiýada tablisada ýerleşdirilýär, sebäbi bahanyň hash kody null, это – всегда 0.

  • Indiki ädimde, hash bahasy usuly çagyrmak arkaly alnan açaryň hash koduny ulanyp hasaplanýar hashCode(). Bu hash bahasy, obýektiň ýerleşdiriljek massiwindäki ýagdaýy hasaplamak üçin ulanylýar Entry. JDK dizaýnerleri , pes ýazylan funksiýa hashCode()gaty ýokary ýa-da gaty pes hash bahasyny yzyna gaýtaryp biler diýip çaklaýarlar. Bu meseläni çözmek üçin başga bir funksiýa hödürlediler hash()we hash bahasyny massiwiň ululygyna laýyk etmek üçin bir obýektiň hash bahasyny oňa geçirdiler.

  • Indi funksiýa indexFor(hash, table.length)obýektiň nirede goýuljakdygyny takyk hasaplamak üçin çagyrylýar Entry.

  • Esasy bölegi şu ýerden başlaýar. Indi iki sany deň däl obýektiň deň hash kodlarynyň bolup biljekdigini bilýänlerimize esaslanyp, bir sorag berýäris: iki dürli jisim [çelek] massiwinde şol bir ýerde ýerleşdirilermi? Jogap LinkedList. .Adyňyzda bolsa, synpyň Entry"" häsiýeti bar next. Bu atribut elmydama zynjyryň indiki obýektini görkezýär. Bu edil özüni alyp barşy LinkedList.
Şeýlelik bilen, obýektler Entrygörnüşde saklanýar LinkedList. Haçan-da bir obýekt Entrybelli bir ýerde ýerleşdirilmeli bolsa, “HashMap” şol ýerde eýýäm ýazgynyň bardygyny ýa-da ýokdugyny barlaýar. Giriş ýok bolsa, obýekt şu ýagdaýda ýerleşdirilýär. Şeýle-de bolsa, bu ýagdaýda eýýäm bir obýekt bar bolsa, indiki atribut barlanýar. Eger gaýdyp gelse nullwe häzirki obýekt Entryindiki baglanyşyk bolar LinkedList. Indiki üýtgeýji bolmasa null, prosedura indiki tapylýança gaýtalanýar null. Başga bir obýekti başga bir gymmaty bolan, ýöne öňküsi ýaly açar goýsak näme etmeli? Logika görä, bu köne bahanyň çalşylmagyna sebäp bolmaly. Bu nähili bolup geçýär? Umuman, obýektiň ýagdaýyny kesgitlänsoň , hasaplanan ýagdaýa Entrygeçende , her bir obýekt üçin açar deňeşdirme usuly diýilýär . Bu obýektleriň hemmesiniň meňzeş hash kodlary bolup biler, ýöne usul hakyky meňzeşligini barlar. Bu diňe içindäki bahany çalşar . Şeýlelikde, “HashMap” ähli düwmeleriň özboluşlylygyny kepillendirýär. LinkedListHashMapEntryEntryLinkedListequals()Entry

Java () usuly nädip işleýär?

Indi açar bahaly jübütleriň nädip saklanýandygy barada düşünjämiz bar HashMap. Indiki uly sorag: Bir obýekt “HashMap” -dan bir usula geçirilende näme bolýar get()? Obýektiň bahasy nädip kesgitlenýär? Jogabyny eýýäm bilmelidiris, sebäbi usulyň açarynyň özboluşlylygynyň kesgitleniş usuly put()usulyň ulanýan logikasyna eýedir get(). HashMapArgument hökmünde geçen obýektiň açaryny kesgitlänsoň, diňe degişli bahany yzyna gaýtaryp berýär Entry. Gabat gelýän tapylmasa, usul get()gaýdyp geler null. Koda göz aýlalyň:
public V get(Object key) {
if (key == null)
return getForNullKey();
int hash = hash(key.hashCode());
for (Entry<k,V>e=table[indexFor(hash,table.length)];e!=null;e=e.next){
Object k;
if (e.hash == hash && ((k = e.key) == key || key.equals(k)))
return e.value;
}
return null;
}
put()Aboveokardaky kod şu wagta çenli usula meňzeýär.Ondan if (e.hash == hash && ((k = e.key) == key || key.equals(k)))soň diňe obýektiň bahasyny yzyna gaýtaryp berýär.

Bellikler

  • Obýektde saklanjak maglumatlar gurluşy, ady we görnüşi Entrybolan massiwdir .tableEntry
  • Toplumdaky her aýratyn pozisiýa çelek diýilýär, sebäbi LinkedListobýektleriň birinji elementini öz içine alyp biler Entry.
  • hashCode()Obýektiň ýagdaýyny hasaplamak üçin açar talap edilýär Entry.
  • equals()Açar kartadaky açaryň özboluşlylygyny barlamak üçin ulanylýar ( map).
  • hashCode()we bahalar usullarda we içinde equals()ulanylmaýar .get()set()HashMap
  • Gymmatlygy bolan düwmeler üçin hash kody nullelmydama 0 bolýar. Şeýle obýekt Entryelmydama massiwiň nol ýagdaýynda saklanar.
Bu makalada pikirlerimi dogry düşündirdim diýip umyt edýärin. Rorsalňyşlyklar tapsaňyz ýa-da soraglaryňyz bar bolsa, teswirlerde goýmagyňyzy haýyş edýäris. Okuwyňyz gutly bolsun!
Teswirler
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION