JavaRush /Блоги Java /Random-TG /HashMap дар Java чӣ гуна кор мекунад
GeorgeThreeD
Сатҳи

HashMap дар Java чӣ гуна кор мекунад

Дар гурӯҳ нашр шудааст
Аксарияти шумо розӣ мешавед HashMap, ки имрӯз мавзӯи дӯстдоштатарин барои муҳокима ҳангоми мусоҳибаҳост. Баъзан ман бо ҳамкасбони худ чунин сӯҳбатҳо мекардам ва ин воқеан кӯмак мекард. Акнун ман бо шумо чунин сӯҳбат хоҳам кард. Чӣ тавр HashMap дар Java кор мекунад - 1Ман гумон мекунам, ки агар шумо ба корҳои дохилӣ ва кори HashMap таваҷҷӯҳ дошта бошед, пас шумо аллакай бо асосҳои HashMap шинос ҳастед , бинобар ин ман ин қисмро мегузарам. Аммо агар шумо дар ин кор нав бошед, ман тавсия медиҳам, ки ба сайти Java Docs равед . Пеш аз он ки мо идома диҳем, ман ба шумо тавсия медиҳам, ки мақолаи пешинаи маро бубинед: Кор бо hashCode ва усули баробар дар Java. Мундариҷаи ин мақола:
  1. Ягона ҷавоби имконпазир.
  2. Hashing чист.
  3. Каме дар бораи синф Entry.
  4. Чӣ кор мекунад put().
  5. Чӣ тавр усул кор мекунад get().
  6. Қайдҳо

Ягона ҷавоби имконпазир

Агар касе аз ман бипурсад, ки шарҳ диҳам " HashMap чӣ гуна кор мекунад?" ", Ман танҳо ҷавоб медиҳам:" Мувофиқи принсипҳои Hashing . Ин соддатар буда наметавонист. Барои фаҳмидани ин ва гирифтани ҷавоби васеъ, шумо бояд боварӣ дошта бошед, ки шумо асосҳои Hashing-ро медонед. Дуруст?

Hashing чист

Хешинг дар соддатарин шакли худ як роҳи табдил додани ҳама гуна тағирёбанда/an object ба рамзи беназир пас аз татбиқи ҳама гуна формула/алгоритм ба хосиятҳои онҳо мебошад. Функсияи hash ҳақиқӣ бояд қоидаи зеринро риоя кунад: Функсияи hash бояд ҳамон codeи хэшро баргардонад, вақте ки он ба an objectҳои якхела ё баробар татбиқ карда мешавад. Ба ибораи дигар, ду an objectи якхела бояд дар навбати худ ҳамон codeҳои хэшро баргардонанд.
Эзоҳ: Ҳама an objectҳо дар java татбиқи стандартии hashCode()функсияи дар синф тавсифшударо мерос мегиранд Object. Ин функсия рамзи хэшро бармегардонад, ки тавассути табдил додани суроғаи дохorи an object ба адад ба даст оварда шудааст, ки боиси эҷоди рамзи беназир барои ҳар як an objectи алоҳида мегардад.
Шумо метавонед дар ин ҷо маълумоти бештар гиред: Кор бо усули hashCode ва баробар дар Java

Як каме дар бораи синфи Entry

Мувофиқи таъриф, харита "an objectест, ки арзишҳо ва калидҳоро дар ҷуфт нигоҳ медорад". Хеле оддӣ, дуруст? Пас, дар HashMap бояд як навъ механизме мавҷуд бошад, ки ҷуфтҳои арзишҳо ва калидҳоро нигоҳ медорад? Ҷавоб - Ҳа. HashMapдорои синфи дохилӣ Entry, ки чунин менамояд:
static class Entry implements Map.Entry
{
        final K key;
        V value;
        Entry next;
        final int hash;
        ...//остальной code тут…
}
Табиист, ки синф Entryдорои Калид ва арзиш ҳамчун атрибутҳо нигоҳ дошта мешавад. Калид ҳамчун қайд карда шудааст finalва мо инчунин ду майдони иловагиро мебинем: nextва hash. Мо кӯшиш хоҳем кард, ки ҳадафи ин соҳаҳоро бо пешрафти мақола фаҳмем.

Усули Java put() чӣ кор мекунад?

Пеш аз он ки мо ба татбиқи метод ғарқ шавем put(), фаҳмидани он хеле муҳим аст, ки мисолҳои синф Entryдар массив нигоҳ дошта мешаванд. Синфи HashMap ин тағирёбандаро чунин муайян мекунад:
/**
* Размер таблицы, изменяется при необходимости. Длина всегда должна быть
* кратна двум!
*/
    transient Entry[] table;
Акнун ба codeи татбиқи усул нигаред 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;
}
Биёед онро қадам ба қадам муайян кунем:
  • Пеш аз ҳама, мо тафтиш мекунем, ки калид вуҷуд дорад. Агар калид мавҷуд набошад ( null), арзиш дар ҷадвал дар мавқеи сифр ҷойгир карда мешавад, зеро codeи hash барои арзиш null, аст это – всегда 0.

  • Дар қадами навбатӣ, арзиши hash бо истифода аз codeи хэши калид, ки тавассути занги метод ба даст оварда шудааст, ҳисоб карда мешавад hashCode(). Ин арзиши хэш барои ҳисоб кардани мавқеъ дар массив, ки an object ҷойгир карда мешавад, истифода мешавад Entry. Тарроҳони JDK тахмин мезаданд, ки функсияи нодуруст навишташуда hashCode()метавонад арзиши хэшро баргардонад, ки хеле баланд ё хеле паст аст. Барои ҳалли ин мушкилот, онҳо hash()функсияи дигарро ҷорӣ карданд ва арзиши хэш-и an objectро ба он интиқол доданд, то арзиши хэш ба андозаи массив мувофиқат кунад.

  • Ҳоло функсия indexFor(hash, table.length)барои ҳисоб кардани мавқеи дақиқе, ки an object дар куҷо ҷойгир карда мешавад, даъват карда мешавад Entry.

  • Дар ин ҷо қисми асосӣ оғоз мешавад. Акнун, дар асоси он чизе ки мо медонем, ки ду an objectи нобаробар метавонанд codeҳои баробар дошта бошанд, мо савол медиҳем: Оё ду an objectи гуногун дар массиви [сатил] дар як ҷой ҷойгир карда мешаванд? Ҷавоб ин аст LinkedList. Агар дар хотир доред, синф Entryдорои атрибути " next". Ин атрибут ҳамеша ба an objectи навбатии занҷир ишора мекунад. Ин маҳз рафтор аст LinkedList.
Ҳамин тавр, an objectҳо Entryдар шакл нигоҳ дошта мешаванд LinkedList. Вақте ки an object Entryбояд дар як макони мушаххас ҷойгир карда шавад, HashMap тафтиш мекунад, ки оё дар он макон аллакай сабт мавҷуд аст ё не. Агар ягон вуруд мавҷуд набошад, an object дар ин мавқеъ ҷойгир карда мешавад. Аммо агар дар ин мавқеъ аллакай an object мавҷуд бошад, атрибути навбатӣ тафтиш карда мешавад. Агар он баргардад nullва an objectи ҷорӣ Entryпайванди навбатӣ дар LinkedList. Агар тағирёбандаи навбатӣ набошад null, тартиби дигар то пайдо шудани он такрор карда мешавад null. Чӣ мешавад, агар мо an objectи дигареро бо арзиши дигар, вале калиди ҳамон калид гузорем? Мантиқан ин бояд боиси иваз шудани арзиши кӯҳна шавад. Ин чӣ гуна рӯй медиҳад? Умуман, пас аз муайян кардани мавқеи an object Entry, ҳангоми гузаштан LinkedListба мавқеи ҳисобшуда, HashMapон усули муқоисаи калидии ҳар як an objectро даъват мекунад Entry. Ҳамаи ин Entryan objectҳо LinkedListметавонанд рамзҳои хэш монанд дошта бошанд, аммо усул equals()шабоҳати ҳақиқиро тафтиш мекунад. Ин танҳо арзишро дар дохor Entry. Ҳамин тариқ, HashMap ягонагии ҳамаи калидҳоро кафолат медиҳад.

Усули Java get() чӣ гуна кор мекунад?

Ҳоло мо тасаввуроте дорем, ки чӣ гуна ҷуфтҳои калидӣ-арзиш дар HashMap. Саволи навбатии калон ин аст: Вақте ки an object аз HashMap ба метод гузаронида мешавад, чӣ мешавад get()? Арзиши an object чӣ гуна муайян карда мешавад? Мо бояд аллакай ҷавобро донем, зеро тарзи муайян кардани ягонагии калид дар усул put()ҳамон мантиқеро дорад, ки ин усул татбиқ мешавад get(). Вақте ки HashMapон калиди an objectи ба сифати аргумент додашударо муайян мекунад, он танҳо арзиши мувофиқро бармегардонад Entry. Агар ягон мувофиқат пайдо нашавад, усул get()бармегардад null. Биёед codeро бубинем:
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()то ин лаҳза монанд аст.Баъд if (e.hash == hash && ((k = e.key) == key || key.equals(k)))аз он танҳо арзиши an objectро бармегардонад.

Қайдҳо

  • Сохтори маълумоте, ки дар an object нигоҳ дошта мешавад, Entryмассив бо ном tableва намуд мебошад Entry.
  • Ҳар як мавқеи инфиродӣ дар массив сатил номида мешавад, зеро он метавонад унсури якуми LinkedListan objectҳоро дар бар гирад Entry.
  • hashCode()Калид барои ҳисоб кардани мавқеи an object лозим аст Entry.
  • equals()Калид барои санҷидани ягонагии калид дар харита ( map) истифода мешавад.
  • hashCode()ва equals()Арзишҳо дар усулҳо get()ва set()дар HashMap.
  • Рамзи хэш барои калидҳои дорои арзиш nullҳамеша 0 аст. Ва чунин an object Entryҳамеша дар мавқеи сифрии массив нигоҳ дошта мешавад.
Умедворам, ки ман дар ин мақола фикрҳои худро дуруст баён кардам. Агар шумо хатогиҳо пайдо кунед ё саволе дошта бошед, лутфан онҳоро дар шарҳҳо гузоред. Омӯзиши хушбахтона!
Шарҳҳо
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION