Sobes.tech
Junior — Middle

Ի՞նչ չափի հիշողություն է հատկացվում HashSet-ի ներսում երկու տարր պահելու համար, որոնցից մեկը ունի hashCode 0, իսկ մյուսը՝ 1000000։

sobes.tech AI

Պատասխան AI-ից

Java-յում HashSet-ը իրականացվում է HashMap-ի հիման վրա, որտեղ տարրերը պահվում են որպես բանալիներ: HashMap-ի ներսում օգտագործվում է բաքերի (table) զանգված, որի չափը միշտ երկուի ուժեղն է, նախնական 16:

Առաջին տարր ավելացնելիս, HashSet-ը հատկացում է 16 բաքերի զանգված: Յուրաքանչյուր բաք կամ null է, կամ կապված ցանկ (կամ ծառ, եթե շատ տարրեր կան):

Երկու տարրերի համար, որոնց hashCode-ն 0 և 1000000 են՝

  • Բաքի ինդեքսը հաշվվում է որպես hash & (table.length - 1):
  • hashCode 0-ի համար ինդեքսը կլինի 0:
  • hashCode 1000000-ի համար (երկբայ ձևով), ինդեքսը կլինի 1000000 & 15:

1000000 թիվը երկբայ ձևով ավարտվում է 0-ով, հետևաբար ինդեքսը կլինի 0:

Այսպիսով, երկու տարրերն էլ ընկնում են նույն բաքը (ինդեքս 0), և այդ բաքի ներսում կլինի երկու տարրից կազմված կապված ցանկ:

Հիշողության օգտագործում:

  • Բաքերի զանգված՝ 16 հղումներ (յուրաքանչյուրը 4 կամ 8 բայթ, JVM-ի վրա կախված):
  • Երկու Node օբյեկտներ (HashMap-ի ներքին տարրեր), որոնք պարունակում են բանալին, արժեքը (HashSet-ի համար՝ կեղծ արժեք), հաջորդ տարրին հղում և hash:

Ընդհանուր առմամբ, հատկացվում է 16 տարրերի զանգված և երկու Node օբյեկտ, որոնք կապված են շղթայի մեջ մեկ բաքում:

Օրինակ՝

HashSet<Integer> set = new HashSet<>();
set.add(0);       // hashCode = 0
set.add(1000000); // hashCode = 1000000

Երկու տարրերն էլ գտնվելու են ինդեքս 0 բաքում, ինչը կարող է վատացնել որոնման արդյունավետությունը։