Ի՞նչ չափի հիշողություն է հատկացվում 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 բաքում, ինչը կարող է վատացնել որոնման արդյունավետությունը։