get
"," HashMap -da usullaryň işlemeginiň içerki mehanizmi näme put
? ". Bu ýerde ýönekeý bir mysal ulanyp içerki işlemegi düşündirmäge synanyşaryn. Kän bir teoriýa girmän, has gowy düşünip, soňra Java-da usullaryň nähili işleýändigini görüp bilersiňiz, mysal bilen başlarys get
. put
Geliň, gaty ýönekeý bir mysal alalyň. Biziň synpymyz bar (iňlisçe “ýurt”), synp obýektini açar , bu ýurduň paýtagtynyň ady bolsa baha hökmünde Country
ulanarys . Country
Aşakda açar bahaly jübütiň hash kartasynda nädip saklanjakdygyna düşünmäge kömek edýän mysal.
1..urt.java
package org.arpit.javapostsforlearning;
public class Country {
String name;
long population;
public Country(String name, long population) {
super();
this.name = name;
this.population = population;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public long getPopulation() {
return population;
}
public void setPopulation(long population) {
this.population = population;
}
// если длина имени в an objectе Country - четное число,
// то возвращаем 31(любое случайное число), а если нечетное - 95 (любое случайное число).
// указанный ниже метод - это не самый лучший способ генерации хеш-codeа,
// но мы воспользуемся им для более четкого понимания хеш-карт.
@Override
public int hashCode() {
if(this.name.length()%2==0)
return 31;
else
return 95;
}
@Override
public boolean equals(Object obj) {
Country other = (Country) obj;
if (name.equalsIgnoreCase((other.name)))
return true;
return false;
}
}
Usullar we deňlikler barada has köp düşünmek we öwrenmek isleseňiz , şu baglanyşygahashcode
eýerip bilersiňiz .
2. HashMapStructure.java (esasy synp)
import java.util.HashMap;
import java.util.Iterator;
public class HashMapStructure {
/**
* @author Arpit Mandliya
*/
public static void main(String[] args) {
Country india=new Country("India",1000);
Country japan=new Country("Japan",10000);
Country france=new Country("France",2000);
Country russia=new Country("Russia",20000);
HashMap<country,string> countryCapitalMap=new HashMap<country,string>();
countryCapitalMap.put(india,"Delhi");
countryCapitalMap.put(japan,"Tokyo");
countryCapitalMap.put(france,"Paris");
countryCapitalMap.put(russia,"Moscow");
Iterator<country> countryCapitalIter=countryCapitalMap.keySet().iterator();//установите
//debug-точку на этой строке(23)
while(countryCapitalIter.hasNext())
{
Country countryObj=countryCapitalIter.next();
String capital=countryCapitalMap.get(countryObj);
System.out.println(countryObj.getName()+"----"+capital);
}
}
}
Indi aralyk nokadyny 23-nji setire düzüň we run -> debug as-> java programmasyny işlediň (terjimeçiniň belligi - Eclipse üçin güýje girýär). Programma 23-nji setirde ýerine ýetirilmegini bes eder, şondan soň countryCapitalMap- a sag basyň we sagat saýlaň . Munuň ýaly tablisany görersiňiz: Ine, aşakdakylary görýäris:
-
Entry[]
16 sany öýjükli massiw bartable
; -
Bu massiw synpyň obýektlerini saklaýar
Entry
. SynpyňHashMap
içki synpy bar -Entry
. Bu synpyň mysallary esasy bahaly jübütlerdir. Synp gurluşyna göz aýlalyňEntry
: -
Her gezek hash kartasynda açar bahaly jübüt döretmäge synanyşanymyzda, bu jübüt üçin synp obýekti dörediler
Entry
we ýokardaky tablisada saklanarEntry[]
. Indi bu tablisanyň nirede ýazyljakdygy (haýsy öýjükde) ýazyljakdygy hakda pikirlenmeli. Açar bahaly jübütdäki açar üçin hash kody ulanylýarhashcode()
. Bu hash kody bolsa tablisanyň öýjük belgisini hasaplamak üçin ulanylýarEntry[]
; -
Indi, tablisanyň 10-njy öýjügine seretseňiz, bir synp obýektini
Entry
görersiňizHashMap$Entry
; - 4 açar bahaly jübüt goşduk, ýöne massiwde bary-ýogy 2 bar !!! Sebäbi 2 obýektiň hash kody bar bolsa, şol bir öýjükde saklanar. Emma nähili? Obýektler baglanyşyk sanawy () hökmünde saklanar
LinkedList
.
static class Entry implements Map.Entry
{
final K key;
V value;
Entry next;
final int hash;
...//продолжение codeа
}
Hashcode for Japan = 95 так How длина слова Japan имеет нечетное количество букв.
Hashcode for India = 95 так How длина слова India имеет нечетное количество букв.
HashCode for Russia = 31 так How длина слова Russia имеет четное количество букв.
HashCode for France = 31 так How длина слова France имеет четное количество букв.
Aşakdaky surat baglanyşdyrylan sanawyň ideýasyny düşündirer: Indi hash kartalarynyň gurluşy barada eýýäm düşüneniňizden soň, geliň put
we usullara geçeliň get
.
Goý:
Bu usulyň nähili ulanylýandygyny göreliň:/**
* Метод связывает указанное meaning с указанным ключом в данной хэш-карте. Если
* карта до этого уже содержала некоторое meaning, соответствующее этому ключу,
* то старое meaning заменяется на указанное.
* @param key
* ключ, с которым связывается указанное meaning
* @param value
* meaning, связываемое с указанным ключом
* @возвращает meaning связанное с <tt>ключом</tt>, or <tt>null</tt>,
* если ниHowое meaning не соответствует <tt>ключу</tt>. ( Возврат <tt>null</tt>
* может так же говорить о том, что в карте заведомо <tt>null</tt> был связан с
* <tt>ключом</tt>.)
*/
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;
}
Indi bu koda ädimme-ädim düşünmäge synanyşalyň:
-
key
Obýektiň deňligini barlaýarysnull
. Şeýle bolsa, obýektkey
ýerinde saklanar,table[0]
sebäbi hash kodynull
hemişe 0; -
Ondan soň, hash koduny hasaplaýan obýektiň
key
usuly diýýäris.hashcode()
Bu hash kody, synp obýektiniň saklanjak massiw öýjügini kesgitlemek üçin ulanylýarEntry
. Käwagt bu funksiýanyňhashcode
gaty ussatlyk bilen ýazylmandygy sebäpli JDK döredijiler başga bir funksiýa döretdiler -hash()
bu öň hasaplanan hash koduny argument hökmünde kabul edýär. Bu funksiýa barada has jikme-jik okamak isleseňiz, baglanyşyga eýerip bilersiňiz ; -
indexFor(hash,table.length)
table
synp obýektiniň saklanjak kesgitlenýän massiwinde belli bir öýjügi kesgitlemek üçin ulanylýarEntry
; -
Mysalymyzda görşümiz ýaly, iki obýektiň
key
hash kody bar bolsa (bu ýagdaý çaknyşyk diýilýär), onda olar baglanyşyk sanawy görnüşinde saklanar. Şonuň üçin bu etapda sanawymyzy gaýtalaýarys: -
täze hasaplanan öýjük boş bolsa, synp obýekti
Entry
gönüden-göni bu öýjüge ýazylar; -
next
bu öýjükde eýýäm haýsydyr bir obýekt bar bolsa, meýdany deň bolan elemente gaýtalanýarnull
. Ondan soň synp obýektimizEntry
sanawda indiki bolýar; -
şol bir obýekti ýene goşsak näme etmeli
key
? Logika görä, köne bahany çalyşmaly. Hawa, şeýle bolar.equals()
Gaýtalama wagtynda düwmeler ( ) usuly bilen deňeşdirilerkey.equals(k)
. Netije dogry bolsa, köne baha häzirki obýektiň bahasy bilen çalşyrylarEntry
.
Al:
Indi usulyň ulanylyşyna göz aýlalyň/**
* returns meaning, которое соответствует указанному ключу, or {@code null}, если
* данная карта не содержит пары с указанным ключом.
*
*
* <p>
* Более точно, если в данной карте содержится такой ключ {@code k}
* с соответствующим ему meaningм {@code v}, что {@code (key==null ? k==null : key.equals(k))},
* то метод возвращает {@code v}; в противном случае возвращается {@code null}.
* (может быть не более одной такой пары)
*
* </p><p>
* Возвращенное meaning {@code null} не <i>обязательно</i> говорит о том, что
* в карте нет пары с таким указанным ключом; а возможно, что в карте однозначно
* указано соответствие этого ключа со meaningм {@code null}.
* Можно воспользоваться операцией {@link #containsKey containsKey}, чтобы
* отличить эти два случая
* @see #put(Object, Object)
*/
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;
}
Indi goýlan usulyň hashmaplarda nähili işleýändigine düşünip, goýlan usulyň işleýşine düşünmek gaty
get
ýönekeý. Haş kartasyndan baha almak üçin haýsydyr bir açary geçireniňizde:
-
Obýekt
Ekey deňlik üçin synag edilýär null
. Şeýle bolsa, öýjükde saklanýan obýektiň bahasy yzyna gaýtarylartable[0]
; -
hashcode()
Esasy obýektiň hash koduny hasaplaýan usuly bar ; -
indexFor(hash,table.length)
table
synp obýektini aljak belli bir massiw öýjügini kesgitlemek üçin ulanylýarEntry
; -
Toplum öýjük belgisini alandan soň,
table
sanawda gaýtalanar we usuly ulanyp düwmeleri deňeşdirerequals()
. Netije dogry bolsa, obýektiň bahasy yzyna gaýtarylarEntry
, ýogsam -null
.
Rememberatlamaly zatlar:
-
Bu synpda esasy baha jübütlerini saklaýan
HashMap
içki synp bar ;Entry
-
Synpyň obýektleri diýilýän
Entry
massiwde saklanýar ;Entry[ ]
table
-
Bir massiw öýjügine çelek diýilýär we baglanyşyk sanawynyň birinji elementini saklaýar;
-
hashcode()
Obýekt usulykey
bu synp obýektiniň çelgesini tapmak üçin ulanylýarEntry
; -
Iki obýektiň açary birmeňzeş hash kody bolsa, şol bir çelekde saklanar
table
; -
equals()
Obýektiň usuly,key
özboluşlylygyny tassyklamak üçin ulanylýar; -
Usullar
equals()
wehashcode()
obýektlervalue
asla ulanylmaýar.
GO TO FULL VERSION