JavaRush /جاوا بلاگ /Random-SD /HashMap جاوا ۾ ڪيئن ڪم ڪندو آهي؟
gnev
سطح

HashMap جاوا ۾ ڪيئن ڪم ڪندو آهي؟

گروپ ۾ شايع ٿيل
HashMap جاوا ۾ ڪيئن ڪم ڪندو آهي؟  - 1اڪثر انٽرويوز ۾ ماڻهو سوال پڇندا آهن جهڙوڪ " هاش ميپ جاوا ۾ ڪيئن ڪم ڪندو آهي؟" 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 لائن تي عمل کي روڪيندو، جنهن کان پوء ملڪ ڪيپيٽل ميپ تي صحيح ڪلڪ ڪريو ۽ واچ چونڊيو . توھان ھن طرح ھڪڙي جدول ڏسندا: HashMap جاوا ۾ ڪيئن ڪم ڪندو آهي؟  - 2ھتي اسان ھيٺيون ڏسون ٿا:
  1. هتي Entry[]16 سيلن جو هڪ صف آهي جنهن جو نالو آهي table؛

  2. هي صف ڪلاس جون شيون محفوظ ڪري ٿو Entry. ڪلاس HashMap۾ هڪ اندروني طبقو آهي - Entry. ۽ هن طبقي جا مثال اهم-قدر جوڙو آهن. اچو ته ڪلاس جي جوڙجڪ تي هڪ نظر وجهون Entry:

  3. static class Entry implements Map.Entry
            {
                    final K key;
                    V value;
                    Entry next;
                    final int hash;
                    ...//продолжение codeа
            }
  4. هر دفعي اسان ڪوشش ڪريون ٿا هڪ اهم-قدر جوڙو ٺاهڻ لاءِ هيش نقشي ۾، ان جوڙي لاءِ هڪ ڪلاس شئي ٺاهي ويندي Entry۽ اها مٿي ڏنل جدول ۾ محفوظ ڪئي ويندي Entry[]. ۽ ھاڻي توھان کي سوچڻ گھرجي ته ھن جدول ۾ اھو اعتراض ڪٿي لکيل ھوندو (ڪھڙي سيل ۾). هڪ اهم-قدر جي جوڙي ۾ هڪ اهم لاء، هڪ هيش ڪوڊ استعمال ڪندي ڳڻيو ويندو آهي hashcode(). ۽ هي هيش ڪوڊ استعمال ڪيو ويندو آهي ٽيبل سيل نمبر ڳڻڻ لاءِ Entry[]؛

  5. هاڻي جيڪڏهن توهان ٽيبل جي سيل 10 تي نظر وجهو ته توهان کي هڪ ڪلاس شئي نظر ايندي Entryجنهن جو نالو آهي HashMap$Entry؛

  6. اسان 4 اهم-قدر جوڙو شامل ڪيو، پر صف ۾ صرف 2 آھن!!! اهو ئي سبب آهي ته جيڪڏهن 2 شيون ساڳيون هيش ڪوڊ آهن، پوء اهي ساڳئي سيل ۾ محفوظ ڪيا ويندا. پر ڪيئن؟ شيون هڪ ڳنڍيل فهرست جي طور تي محفوظ ڪيون وينديون ( LinkedList).
ھتي آھي اسان جي اهم-قدر جوڙن لاءِ ھيش ڪوڊ ڪيئن ڳڻيو ويندو.
Hashcode for Japan = 95 так How длина слова Japan имеет нечетное количество букв.
Hashcode for India = 95 так How длина слова India имеет нечетное количество букв.
HashCode for Russia = 31 так How длина слова Russia имеет четное количество букв.
HashCode for France = 31 так How длина слова France имеет четное количество букв.
هيٺ ڏنل انگ اکر ڳنڍيل فهرست جي خيال جي وضاحت ڪندو: HashMap جاوا ۾ ڪيئن ڪم ڪندو آهي؟  - 3هاڻي ته توهان کي اڳ ۾ ئي ڄاڻ آهي ته هيش نقشن جي جوڙجڪ بابت، اچو ته اڳتي وڌون 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;
 }
ھاڻي اچو ته ھن ڪوڊ کي قدم بہ قدم سمجھڻ جي ڪوشش ڪريون:
  1. keyاسان برابري لاء اعتراض چيڪ ڪريو null. جيڪڏهن ائين آهي، ته پوء اعتراض keyهنڌ ۾ محفوظ ڪيو ويندو table[0]ڇو ته هيش ڪوڊ nullهميشه لاء 0 آهي؛

  2. اڳيون، اسان اعتراض جو keyطريقو سڏين ٿا hashcode()، جيڪو حساب ڪندو ان جي هيش ڪوڊ. هي هيش ڪوڊ استعمال ڪيو ويندو آهي صف جي سيل کي طئي ڪرڻ لاءِ جتي ڪلاس اعتراض کي محفوظ ڪيو ويندو Entry. ڪڏهن ڪڏهن ائين ٿئي ٿو ته هي فنڪشن hashcodeتمام مهارت سان نه لکيو ويو آهي، تنهن ڪري JDK ڊولپرز هڪ مختلف فنڪشن ٺاهيا آهن hash()، جيڪو اڳ ۾ حساب ڪيل هيش ڪوڊ کي دليل طور وٺندو آهي. جيڪڏهن توهان هن فنڪشن بابت وڌيڪ تفصيل سان پڙهڻ ۾ دلچسپي رکو ٿا، توهان لنڪ جي پيروي ڪري سگهو ٿا ؛

  3. indexFor(hash,table.length)صف ۾ هڪ مخصوص سيل کي بيان ڪرڻ لاء استعمال ڪيو ويو آهي tableجنهن ۾ هڪ طبقي اعتراض کي محفوظ ڪيو ويندو Entry؛

  4. جيئن اسان پنهنجي مثال ۾ ڏٺو، جيڪڏهن ٻه شيون 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تمام سادو آھي. جڏهن توهان هيش نقشي مان قيمت حاصل ڪرڻ لاءِ ڪنهن به طريقي کي پاس ڪندا آهيو:
  1. هڪ اعتراض ايڪي کي برابري لاءِ آزمايو ويو آهي null. جيڪڏهن ائين آهي، ته سيل ۾ محفوظ ڪيل اعتراض جي قيمت واپس ڪئي ويندي table[0]؛

  2. اهم اعتراض هڪ طريقو آهي hashcode()جنهن کي سڏيو ويندو آهي هيش ڪوڊ جي حساب سان؛

  3. indexFor(hash,table.length)هڪ مخصوص صف جي سيل کي طئي ڪرڻ لاء استعمال ڪيو ويو آهي tableجنهن مان هڪ طبقي اعتراض کڻڻ Entry؛

  4. ايري سيل نمبر حاصل ڪرڻ کان پوء، tableاهو فهرست جي ذريعي ٻيهر ورجائي ٿو ۽ طريقي سان استعمال ڪندي چيڪن جو مقابلو ڪندو equals(). جيڪڏهن نتيجو صحيح آهي، ته اعتراض جو قدر واپس ڪيو ويندو Entry، ٻي صورت ۾ - null.

ياد رکڻ جون شيون:

  • ڪلاس HashMap۾ هڪ اندروني طبقو آهي Entryجيڪو ذخيرو ڪري ٿو اهم-قدر جوڙو؛

  • ڪلاس جون شيون Entryهڪ صف ۾ ذخيرو ٿيل آهن Entry[ ]جنهن کي سڏيو ويندو آهي table؛

  • هڪ صف سيل کي بالٽ سڏيو ويندو آهي ۽ هڪ ڳنڍيل فهرست جي پهرين عنصر کي ذخيرو ڪري ٿو.

  • hashcode()اعتراض جو طريقو keyاستعمال ڪيو ويندو آهي هن طبقي اعتراض جي بالٽ کي ڳولڻ لاء Entry؛

  • جيڪڏهن ٻن شين جي چابيون ساڳيون هيش ڪوڊ آهن، اهي ساڳئي صف جي بالٽ ۾ ذخيرو ٿي ويندا table.

  • equals()ڪنهن شئي جو طريقو keyاستعمال ڪيو ويندو آهي ان جي انفراديت جي تصديق ڪرڻ لاءِ؛

  • طريقا equals()۽ hashcode()شيون valueاستعمال نه ڪيون ويون آهن.

ذريعو
تبصرا
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION