توهان مان گهڻا متفق هوندا ته
توھان ھن بابت وڌيڪ پڙھي سگھوٿا ھتي: hashCode سان ڪم ڪرڻ ۽ جاوا ۾ برابر طريقو
HashMap
، اڄ، انٽرويو دوران بحث لاء سڀ کان وڌيڪ پسنديده موضوع آهي. ڪڏهن ڪڏهن مون کي پنهنجن ساٿين سان ساڳيون ڳالهيون ٿينديون هيون ۽ اهو واقعي مدد ڪندو هو. هاڻي مان توهان سان اهڙو بحث ڪندس. مان سمجهان ٿو ته جيڪڏهن توهان HashMap جي اندروني ۽ ڪم ڪار ۾ دلچسپي رکو ٿا، ته پوء توهان پهريان ئي HashMap جي بنيادي ڳالهين کان واقف آهيو ، تنهنڪري مان اهو حصو ڇڏي ڏيندس. پر جيڪڏھن توھان ھن لاءِ نوان آھيو، مان توھان کي صلاح ڏيان ٿو Java Docs سائيٽ . ان کان اڳ جو اسان اڳتي وڌون، مان توهان کي سفارش ڪريان ٿو ته توهان منهنجي پوئين مضمون کي ڏسو: ڪم ڪرڻ سان گڏ هيش ڪوڊ ۽ جاوا ۾ برابر طريقو. هن مضمون جو مواد:
- صرف ممڪن جواب.
- Hashing ڇا آهي.
- ڪلاس بابت ٿورڙو
Entry
. - ڇا ڪندو آهي
put()
. - طريقو ڪيئن ڪم ڪري ٿو
get()
. - نوٽس
صرف ممڪن جواب
جيڪڏهن ڪو مون کان پڇي ته وضاحت ڪرڻ لاءِ ” هيش ميپ ڪيئن ڪم ڪندو آهي؟ "، مان صرف جواب ڏيندس: " هاشنگ جي اصولن جي مطابق ." اهو آسان نه ٿي سگهي. ھن کي سمجھڻ ۽ وڌايل جواب حاصل ڪرڻ لاءِ، توھان کي پڪ ڪرڻ جي ضرورت آھي ته توھان کي Hashing جي بنيادي ڳالھين جي ڄاڻ آھي. ساڄو؟Hashing ڇا آهي
هيشنگ ان جي آسان ترين شڪل ۾ ڪنهن به متغير/آبجیکٹ کي هڪ منفرد ڪوڊ ۾ تبديل ڪرڻ جو هڪ طريقو آهي ڪنهن به فارمولا/الگورٿم کي انهن جي ملڪيتن تي لاڳو ڪرڻ کان پوءِ. هڪ حقيقي هيش فنڪشن کي هيٺين قاعدي جي پيروي ڪرڻ گهرجي: هڪ هيش فنڪشن کي ساڳيو هيش ڪوڊ موٽڻ گهرجي جڏهن اهو ساڳيو يا برابر شين تي لاڳو ٿئي ٿو. ٻين لفظن ۾، ٻه هڪجهڙائي واريون شيون واپس موٽڻ گهرجن ساڳيا هيش ڪوڊ.hashCode() نوٽ: جاوا ۾ موجود سڀئي شيون ڪلاس ۾ بيان ڪيل فنڪشن جي معياري عمل کي ورثي ۾ رکن ٿيون 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
. جيئن جيئن مضمون اڳتي وڌندو، تيئن اسان انهن شعبن جي مقصد کي سمجهڻ جي ڪوشش ڪنداسين.
جاوا put() طريقو ڇا ڪندو آهي؟
ان کان اڳ جو اسان طريقي جي عمل تي عمل ڪريونput()
، اهو سمجهڻ تمام ضروري آهي ته ڪلاس جا مثال Entry
هڪ صف ۾ محفوظ ٿيل آهن. HashMap ڪلاس هن متغير کي بيان ڪري ٿو:
/**
* Размер таблицы, изменяется при необходимости. Длина всегда должна быть
* кратна двум!
*/
transient Entry[] table;
ھاڻي ھڪڙي نظر وٺو طريقي تي عمل درآمد ڪوڊ 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
)، قيمت ٽيبل ۾ صفر جي پوزيشن تي رکيل آهي ڇاڪاڻ ته قيمت لاء هيش ڪوڊ آهيnull
،это – всегда 0
. - ايندڙ قدم ۾، هيش ويليو ڳڻيو ويندو آهي هيش ڪوڊ استعمال ڪندي حاصل ڪيل چيڪ جو طريقو ڪال ڪندي
hashCode()
. هي هيش ويليو استعمال ڪيو ويندو آهي ڳڻپ ڪرڻ لاءِ پوزيشن جي صف ۾ جتي اعتراض رکيو ويندوEntry
. JDK ڊيزائنرز اهو فرض ڪيو ته هڪ خراب لکيل فعلhashCode()
هڪ هيش قدر واپس ڪري سگهي ٿو جيڪو تمام گهڻو يا تمام گهٽ هو. هن مسئلي کي حل ڪرڻ لاء، انهن هڪ ٻيوhash()
فنڪشن متعارف ڪرايو ۽ هڪ شئي جي هيش ويليو کي ان ۾ پاس ڪيو ته جيئن هيش ويليو کي صف جي سائيز سان ملائي. - ھاڻي فنڪشن کي سڏيو ويندو آھي
indexFor(hash, table.length)
درست پوزيشن کي ڳڻڻ لاء جتي اعتراض رکيل آھيEntry
. - هي آهي جتي مکيه حصو شروع ٿئي ٿو. هاڻي، جنهن جي بنياد تي اسان ڄاڻون ٿا ته - ٻه غير مساوي شيون هڪجهڙا هيش ڪوڊ هوندا آهن، اسان اهو سوال پڇون ٿا: ڇا ٻه مختلف شيون هڪ ئي پوزيشن ۾ رکيا ويندا [bucket] صف ۾؟ جواب آهي
LinkedList
. جيڪڏھن توھان کي ياد آھي، ڪلاسEntry
۾ ھڪڙي خاصيت آھي "next
". هي وصف هميشه زنجير ۾ ايندڙ اعتراض ڏانهن اشارو ڪري ٿو. اهو ئي عمل آهيLinkedList
.
Entry
فارم ۾ محفوظ ٿيل آهن LinkedList
. جڏهن ڪو اعتراض Entry
ڪنهن مخصوص هنڌ تي رکڻو آهي، HashMap چيڪ ڪري ٿو ته ڇا ان هنڌ تي اڳ ۾ ئي ڪا داخلا موجود آهي. جيڪڏهن ڪو داخلا نه آهي، ته اعتراض هن پوزيشن تي رکيل آهي. جيڪڏهن، بهرحال، هن پوزيشن تي اڳ ۾ ئي هڪ اعتراض آهي، ايندڙ وصف چيڪ ڪيو ويو آهي. جيڪڏهن اهو واپس اچي ٿو null
۽ موجوده اعتراض Entry
۾ ايندڙ لنڪ بڻجي وڃي ٿي LinkedList
. جيڪڏهن ايندڙ متغير نه آهي null
، اهو طريقو ايندڙ هڪ لاء بار بار ڪيو ويندو آهي جيستائين اهو ڳولي نه ٿو null
. ڇا جيڪڏهن اسان ٻي شئي کي مختلف قدر سان رکون پر ساڳي چاٻي سان اڳي وانگر؟ منطقي طور تي ان جي نتيجي ۾ پراڻي قدر کي تبديل ڪيو وڃي. اهو ڪيئن ٿو ٿئي؟ عام طور تي، ڪنهن شئي جي پوزيشن جو تعين ڪرڻ کان پوءِ ، ڳڻپيوڪر پوزيشن ڏانهن Entry
وڃڻ دوران ، ان کي هر شئي لاءِ اهم compare طريقو سڏين ٿا . انهن سڀني شين ۾ هڪجهڙا هيش ڪوڊ هوندا، پر اهو طريقو صحيح هڪجهڙائي جي جانچ ڪندو. اهو صرف اندر جي قيمت کي تبديل ڪندو . اهڙيء طرح، HashMap سڀني ڪنجين جي انفراديت جي ضمانت ڏئي ٿي. LinkedList
HashMap
Entry
Entry
LinkedList
equals()
Entry
Java get() طريقو ڪيئن ڪم ڪندو آهي؟
هاڻي اسان کي هڪ خيال آهي ته ڪيئن اهم-قدر جوڙو ۾ ذخيرو ٿيل آهنHashMap
. ايندڙ وڏو سوال اهو آهي ته: ڇا ٿيندو جڏهن ڪا شئي HashMap کان هڪ طريقي سان گذري ويندي آهي get()
؟ ڪنهن شئي جي قيمت ڪيئن مقرر ڪئي وئي آهي؟ اسان کي اڳ ۾ ئي جواب ڄاڻڻ گهرجي، ڇاڪاڻ ته طريقي سان جنهن طريقي سان هڪ ڪنجي جي انفراديت کي طئي ڪيو ويندو آهي اهو put()
ساڳيو منطق آهي جيڪو طريقو لاڳو ٿئي ٿو get()
. هڪ دفعو HashMap
اهو طئي ڪري ٿو ته اعتراض جي ڪنجي کي هڪ دليل جي طور تي منظور ڪيو ويو آهي، اهو صرف ان جي قيمت کي واپس ڏئي ٿو Entry
. جيڪڏهن ڪو ميلاپ نه مليو، طريقو get()
واپس ٿيندو null
. اچو ته ڪوڊ تي هڪ نظر رکون:
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)))
، ان کان پوء اهو صرف اعتراض جي قيمت ڏي ٿو.
نوٽس
- ڊيٽا جو ڍانچو جيڪو ڪنهن شئي ۾ محفوظ ڪيو وڃي ٿو
Entry
اهو نالوtable
۽ قسم سان هڪ صف آهيEntry
. - صف ۾ هر انفرادي پوزيشن کي بالٽ سڏيو ويندو آهي ڇاڪاڻ ته ان ۾
LinkedList
شيون جي پهرين عنصر شامل ٿي سگهي ٿيEntry
. hashCode()
اعتراض جي پوزيشن کي ڳڻڻ لاءِ ڪنجي گھربل آھيEntry
.equals()
چاٻي کي استعمال ڪيو ويندو آهي چيڪ جي انفراديت کي چيڪ ڪرڻ لاءِ نقشي ۾ (map
).hashCode()
۽equals()
قدر طريقنget()
۽set()
۾ استعمال نه ڪيا ويا آهنHashMap
.- قدر سان ڪيز لاءِ هيش ڪوڊ
null
هميشه 0 هوندو آهي. ۽ اهڙي شئي کيEntry
هميشه صف جي صفر پوزيشن ۾ محفوظ ڪيو ويندو.
GO TO FULL VERSION