get
”، ”هيش ميپ ۾ طريقا ڪيئن ڪم ڪن ٿا ان جو اندروني ميکانيزم ڇا آهي put
؟ هتي آئون هڪ سادي مثال استعمال ڪندي اندروني ڪارڪردگي کي بيان ڪرڻ جي ڪوشش ڪندس. get
تمام گهڻي نظريي ۾ وڃڻ کان سواءِ، اسان هڪ مثال سان شروع ڪنداسين ته جيئن توهان بهتر سمجهي سگهو ۽ پوءِ ڏسو ته put
جاوا ۾ طريقا ڪيئن ڪم ڪن ٿا. اچو ته هڪ تمام سادو مثال وٺون. اسان وٽ ھڪڙو طبقو آھي Country
(انگريزي ”ملڪ“)، اسين ڪلاس اعتراض کي Country
ڪيئي طور استعمال ڪنداسين، ۽ ھن ملڪ جي گاديءَ جو نالو قدر جي طور تي. هيٺ هڪ مثال آهي اسان کي سمجهڻ ۾ مدد لاءِ ته ڪيئن هڪ اهم-قدر جوڙو هڪ هش نقشي ۾ محفوظ ڪيو ويندو.
1. ملڪ.جاوا
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;
}
}
جيڪڏھن توھان چاھيو ٿا سمجھڻ ۽ وڌيڪ سکڻ لاءِ طريقن hashcode
۽ برابريءَ بابت، توھان ھن لنڪ تي عمل ڪري سگھو ٿا .
2. HashMapStructure.java(مين ڪلاس)
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);
}
}
}
ھاڻي بريڪ پوائنٽ کي لڪير 23 تي سيٽ ڪريو ۽ رن -> ڊيبگ ايز-> جاوا ايپليڪيشن (ترجمي ڪندڙ جو نوٽ - ايڪليپس لاءِ صحيح). پروگرام 23 لائن تي عمل کي روڪيندو، جنهن کان پوء ملڪ ڪيپيٽل ميپ تي صحيح ڪلڪ ڪريو ۽ واچ چونڊيو . توھان ھن طرح ھڪڙي جدول ڏسندا: ھتي اسان ھيٺيون ڏسون ٿا:
-
هتي
Entry[]
16 سيلن جو هڪ صف آهي جنهن جو نالو آهيtable
؛ -
هي صف ڪلاس جون شيون محفوظ ڪري ٿو
Entry
. ڪلاسHashMap
۾ هڪ اندروني طبقو آهي -Entry
. ۽ هن طبقي جا مثال اهم-قدر جوڙو آهن. اچو ته ڪلاس جي جوڙجڪ تي هڪ نظر وجهونEntry
: -
هر دفعي اسان ڪوشش ڪريون ٿا هڪ اهم-قدر جوڙو ٺاهڻ لاءِ هيش نقشي ۾، ان جوڙي لاءِ هڪ ڪلاس شئي ٺاهي ويندي
Entry
۽ اها مٿي ڏنل جدول ۾ محفوظ ڪئي وينديEntry[]
. ۽ ھاڻي توھان کي سوچڻ گھرجي ته ھن جدول ۾ اھو اعتراض ڪٿي لکيل ھوندو (ڪھڙي سيل ۾). هڪ اهم-قدر جي جوڙي ۾ هڪ اهم لاء، هڪ هيش ڪوڊ استعمال ڪندي ڳڻيو ويندو آهيhashcode()
. ۽ هي هيش ڪوڊ استعمال ڪيو ويندو آهي ٽيبل سيل نمبر ڳڻڻ لاءِEntry[]
؛ -
هاڻي جيڪڏهن توهان ٽيبل جي سيل 10 تي نظر وجهو ته توهان کي هڪ ڪلاس شئي نظر ايندي
Entry
جنهن جو نالو آهيHashMap$Entry
؛ - اسان 4 اهم-قدر جوڙو شامل ڪيو، پر صف ۾ صرف 2 آھن!!! اهو ئي سبب آهي ته جيڪڏهن 2 شيون ساڳيون هيش ڪوڊ آهن، پوء اهي ساڳئي سيل ۾ محفوظ ڪيا ويندا. پر ڪيئن؟ شيون هڪ ڳنڍيل فهرست جي طور تي محفوظ ڪيون وينديون (
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 имеет четное количество букв.
هيٺ ڏنل انگ اکر ڳنڍيل فهرست جي خيال جي وضاحت ڪندو: هاڻي ته توهان کي اڳ ۾ ئي ڄاڻ آهي ته هيش نقشن جي جوڙجڪ بابت، اچو ته اڳتي وڌون put
۽ طريقن ڏانهن get
.
لڳايو:
اچو ته ڏسو ته هي طريقو ڪيئن استعمال ٿئي ٿو:/**
* Метод связывает указанное 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;
}
ھاڻي اچو ته ھن ڪوڊ کي قدم بہ قدم سمجھڻ جي ڪوشش ڪريون:
-
key
اسان برابري لاء اعتراض چيڪ ڪريوnull
. جيڪڏهن ائين آهي، ته پوء اعتراضkey
هنڌ ۾ محفوظ ڪيو ويندوtable[0]
ڇو ته هيش ڪوڊnull
هميشه لاء 0 آهي؛ -
اڳيون، اسان اعتراض جو
key
طريقو سڏين ٿاhashcode()
، جيڪو حساب ڪندو ان جي هيش ڪوڊ. هي هيش ڪوڊ استعمال ڪيو ويندو آهي صف جي سيل کي طئي ڪرڻ لاءِ جتي ڪلاس اعتراض کي محفوظ ڪيو ويندوEntry
. ڪڏهن ڪڏهن ائين ٿئي ٿو ته هي فنڪشنhashcode
تمام مهارت سان نه لکيو ويو آهي، تنهن ڪري JDK ڊولپرز هڪ مختلف فنڪشن ٺاهيا آهنhash()
، جيڪو اڳ ۾ حساب ڪيل هيش ڪوڊ کي دليل طور وٺندو آهي. جيڪڏهن توهان هن فنڪشن بابت وڌيڪ تفصيل سان پڙهڻ ۾ دلچسپي رکو ٿا، توهان لنڪ جي پيروي ڪري سگهو ٿا ؛ -
indexFor(hash,table.length)
صف ۾ هڪ مخصوص سيل کي بيان ڪرڻ لاء استعمال ڪيو ويو آهيtable
جنهن ۾ هڪ طبقي اعتراض کي محفوظ ڪيو ويندوEntry
؛ -
جيئن اسان پنهنجي مثال ۾ ڏٺو، جيڪڏهن ٻه شيون
key
ساڳيون هيش ڪوڊ آهن (اها صورتحال هڪ ٽڪراء جي طور تي ڄاڻايل آهي)، پوء اهي هڪ ڳنڍيل فهرست جي صورت ۾ محفوظ ڪيا ويندا. تنهن ڪري، هن اسٽيج تي اسان جي فهرست کي ٻيهر ورجائي ٿو: -
جيڪڏهن نئون ڳڻپيو ويو سيل خالي آهي، ته پوء طبقاتي اعتراض
Entry
سڌو سنئون هن سيل ۾ محفوظ ڪيو ويندو؛ -
جيڪڏهن هي سيل اڳ ۾ ئي ڪجهه اعتراض تي مشتمل آهي، ته ان عنصر ڏانهن ورجائي ٿو جنهن جي فيلڊ
next
برابر آهيnull
. ان کان پوء، اسان جي طبقي اعتراضEntry
لسٽ ۾ اڳيان ٿي ويندو آهي؛ -
ڇا جيڪڏهن اسان ساڳيو اعتراض
key
ٻيهر شامل ڪيو؟ منطقي طور، ان کي پراڻي قدر تبديل ڪرڻ گهرجي. ها، ائين ئي ٿيندو. ورجائي دوران، چابيونequals()
(key.equals(k)
) طريقو استعمال ڪندي مقابلو ڪيو ويندو. جيڪڏهن نتيجو صحيح آهي، ته پوء پراڻي قدر کي موجوده اعتراض جي قيمت سان تبديل ڪيو ويندوEntry
.
حاصل ڪريو:
هاڻي اچو ته هڪ نظر وٺو طريقي جي درخواست تي/**
* 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;
}
ھاڻي توھان کي سمجھيو آھي ته ڪيئن پوٽ ميٿڊ hashmaps ۾ ڪم ڪري ٿو، سمجھڻ ته ڪيئن پوٽ ميٿڊ ڪم ڪري ٿو
get
تمام سادو آھي. جڏهن توهان هيش نقشي مان قيمت حاصل ڪرڻ لاءِ ڪنهن به طريقي کي پاس ڪندا آهيو:
-
هڪ اعتراض
ايڪي کي برابري لاءِ آزمايو ويو آهي null
. جيڪڏهن ائين آهي، ته سيل ۾ محفوظ ڪيل اعتراض جي قيمت واپس ڪئي وينديtable[0]
؛ -
اهم اعتراض هڪ طريقو آهي
hashcode()
جنهن کي سڏيو ويندو آهي هيش ڪوڊ جي حساب سان؛ -
indexFor(hash,table.length)
هڪ مخصوص صف جي سيل کي طئي ڪرڻ لاء استعمال ڪيو ويو آهيtable
جنهن مان هڪ طبقي اعتراض کڻڻEntry
؛ -
ايري سيل نمبر حاصل ڪرڻ کان پوء،
table
اهو فهرست جي ذريعي ٻيهر ورجائي ٿو ۽ طريقي سان استعمال ڪندي چيڪن جو مقابلو ڪندوequals()
. جيڪڏهن نتيجو صحيح آهي، ته اعتراض جو قدر واپس ڪيو ويندوEntry
، ٻي صورت ۾ -null
.
ياد رکڻ جون شيون:
-
ڪلاس
HashMap
۾ هڪ اندروني طبقو آهيEntry
جيڪو ذخيرو ڪري ٿو اهم-قدر جوڙو؛ -
ڪلاس جون شيون
Entry
هڪ صف ۾ ذخيرو ٿيل آهنEntry[ ]
جنهن کي سڏيو ويندو آهيtable
؛ -
هڪ صف سيل کي بالٽ سڏيو ويندو آهي ۽ هڪ ڳنڍيل فهرست جي پهرين عنصر کي ذخيرو ڪري ٿو.
-
hashcode()
اعتراض جو طريقوkey
استعمال ڪيو ويندو آهي هن طبقي اعتراض جي بالٽ کي ڳولڻ لاءEntry
؛ -
جيڪڏهن ٻن شين جي چابيون ساڳيون هيش ڪوڊ آهن، اهي ساڳئي صف جي بالٽ ۾ ذخيرو ٿي ويندا
table
. -
equals()
ڪنهن شئي جو طريقوkey
استعمال ڪيو ويندو آهي ان جي انفراديت جي تصديق ڪرڻ لاءِ؛ -
طريقا
equals()
۽hashcode()
شيونvalue
استعمال نه ڪيون ويون آهن.
GO TO FULL VERSION