حامد فرزانه فر
حامد فرزانه فر
خواندن ۳ دقیقه·۱ ماه پیش

Map و Set در جاوا: داستانی از ذخیره‌سازی هوشمند! 🗺️🤝

سلام به همه برنامه نویسهای خلاق و کنجکاو!

امروز قراره عمیق تر شیرجه بزنیم تو دنیای Map  و Set. این بار از یک زاویه تخصصی تر: ساختار داخلی، متدهای  hashCode و  equals و نحوه ذخیره سازی داده ها. آماده اید؟ 🎯




؜Map: استاد کلید و مقدار! 🔑➡️💼

ساختار داخلی Map: پشت پرده چه خبره؟

؜HashMap یکی از پرکاربردترین پیاده سازی های Map در جاواست. تو پشت صحنه، این Map از یه آرایه از باکتها (Buckets) استفاده میکنه. هر باکت یک لیست لینک شده یا در نسخه های جدیدتر، یک Tree هست.

وقتی یه کلید-مقدار اضافه میکنید:

1️⃣ کلید هش میشه (با استفاده از متد hashCode).

2️⃣ مقدار هش تولید شده با تعداد باکتها ماژول (mod) گرفته میشه تا باکت مناسب پیدا بشه.

3️⃣ مقدار شما تو اون باکت ذخیره میشه.


⚠️ وقتی هش برابر است ولی کلیدها متفاوتند؟

اگه دو کلید مقدار هش یکسانی داشته باشن (که بهش Collision میگیم)، جاوا از متد equals استفاده میکنه تا بررسی کنه آیا این کلیدها واقعاً یکی هستن یا نه.

  • اگر برابر باشن: مقدار جدید جایگزین مقدار قبلی میشه.
  • اگر برابر نباشن: مقدار جدید به باکت اضافه میشه (به صورت زنجیره یا درخت).


؜🧪 hashCode و equals در عمل:

این دو متد، قلب رفتار Map هستن:

  • ؜hashCode: مقدار هش کلید رو تولید میکنه. کلیدهای مختلف باید مقادیر هش مختلف تولید کنن.
  • ؜equals: وقتی دو هش برابر هستن، این متد بررسی میکنه آیا دو کلید واقعاً یکسان هستن یا نه.

💡 یادت باشه: اگر تو کلاس شخصی سازی شده ات hashCode رو بازنویسی کردی، حتماً equals رو هم بازنویسی کن.




؜🥁 Set: حافظ اصالت و یکتایی! 🛡️

ساختار داخلی Set:

  • ؜HashSet: از HashMap برای ذخیره داده ها استفاده میکنه. وقتی یه مقدار به HashSet اضافه میکنید، پشت صحنه اون مقدار به عنوان کلید در یک HashMap ذخیره میشه و مقدار مربوطه همیشه ثابت (مثلاً PRESENT) قرار داده میشه.
  • ؜TreeSet: از یک درخت جستجوی دودویی مرتب (Red-Black Tree) استفاده میکنه. این باعث میشه تمام عناصر به ترتیب طبیعی یا با توجه به یک مقایسه گر سفارشی ذخیره بشن.
  • ؜LinkedHashSet: از یک HashMap استفاده میکنه ولی با یک لیست پیوندی داخلی، ترتیب ورود عناصر رو نگه میداره.

؜⚠️ hashCode و equals در Set:

  • وقتی یه مقدار به HashSet اضافه میکنید:

1️⃣ مقدار هش اون محاسبه میشه (با متد hashCode).

2️⃣ اگر هیچ مقدار مشابهی در همون باکت نباشه، مقدار ذخیره میشه.

3️⃣ اگر مقدار هش تکراری باشه، متد equals بررسی میکنه که آیا مقدار دقیقاً تکراریه یا نه.




🤔 بررسی رفتار null در Map و Set

  • ؜HashMap: فقط یک مقدار null به عنوان کلید قبول میکنه. برای مقادیر (Value) هیچ محدودیتی وجود نداره و میتونید چندین مقدار null داشته باشید.
HashMap<String, String> map = new HashMap<>();
map.put(null, "First Null");  // OK!
map.put(null, "Second Null"); // The first value is replaced.
map.put("key1", null);  // OK!


  • ؜TreeMap: برای کلید null اصلاً اجازه نمیده (چون نیاز به مقایسه داره و Comparator با null کار نمیکنه). برای مقادیر (Value) محدودیتی نداره.
TreeMap<String, String> map = new TreeMap<>();
map.put(null, "Value");  // Error!
  • ؜HashSet: فقط یک مقدار null میپذیره.
  • ؜TreeSet: به کل null رو قبول نمیکنه.




🎯 مقایسه سریع Map و Set


📣 حرف آخر: کدام یک؟

حالا که عمیقتر با Map و Set آشنا شدیم، وقتشه که درست تصمیم بگیریم:

  • اگه کلید و مقدار داری، برو سراغ Map.
  • اگه فقط عناصر یکتا میخوای، سراغ Set برو.

شما چطور از hashCode و equals تو پروژه هاتون استفاده میکنید؟ نکته خاصی دارید که اضافه کنید؟ برام بنویسید! ✍️👇

هش
شاید از این پست‌ها خوشتان بیاید