دوره‌ها / JAVA / نقشه‌ها/هَش‌مپ (Java HashMap)

نقشه‌ها/هَش‌مپ (Java HashMap)

15 دقیقه Article

نقشه‌ها (HashMap): جفت‌های کلید و مقدار 🔑💎

در آرایه‌ها ما با "ایندکس عددی" به داده‌ها دسترسی داشتیم. اما در HashMap شما می‌توانید از هر چیزی (مثلاً یک رشته یا یک کد ملی) به عنوان "کلید" (Key) برای دسترسی به یک "مقدار" (Value) استفاده کنید.

۱. ساختار Key-Value

تصور کنید یک دیکشنری دارید. کلمه "سیب" همان کلید است و توضیحات آن مقدار است. در جاوا به این صورت تعریف می‌شود:

{code_block('HashMap<String, String> capitalCities = new HashMap<String, String>();\ncapitalCities.put("Iran", "Tehran");\ncapitalCities.put("Germany", "Berlin");')}

۲. عملیات‌های کلیدی 🏗️

  • put(key, value): اضافه کردن یا بروزرسانی.
  • get(key): دریافت مقدار بر اساس کلید.
  • remove(key): حذف یک جفت.
  • containsKey(key): چک کردن وجود یک کلید (بسیار سریع).
  • size(): تعداد جفت‌ها.
کلیدهای تکراری: کلیدها باید منحصر‌به‌فرد باشند. اگر کلید تکراری put کنید، مقدار جدید جایگزین مقدار قبلی می‌شود. اما "مقدار"ها می‌توانند تکراری باشند.
Hash چیست؟ هشمپ از یک الگوریتم ریاضی به نام Hashing استفاده می‌کند تا کلید شما را به یک عدد تبدیل کند و مستقیماً به آدرسِ داده بپرد. به همین دلیل سرعتِ get در هشمپ حتی برای ۱ میلیارد داده هم تقریباً آنی است!

پیمایش در HashMap:

{code_block('for (String i : capitalCities.keySet()) {\n System.out.println("Country: " + i + " Capital: " + capitalCities.get(i));\n}')}
نکته معماری: هشمپ ترتیبِ ورودِ داده‌ها را حفظ نمی‌کند. اگر ترتیب برایتان مهم است، باید از LinkedHashMap استفاده کنید.
<hr style="margin: 50px 0; border: 0; border-top: 1px dashed rgba(255,255,255,0.1);">

بخش تخصصی: مهندسی داده و بازدهی در جاوا ⚙️💎

در این بخش، به مفاهیمی می‌پردازیم که برای نوشتن برنامه‌های مقیاس‌پذیر و با کارایی بالا (High Performance) ضروری هستند.

۱. تحلیل پیچیدگی زمانی (Big O Notation)

انتخاب کالکشنِ اشتباه می‌تواند سرعت برنامه شما را از میلی‌ثانیه به دقیقه کاهش دهد. مثلاً پر کردن یک ArrayList با ۱ میلیون داده در صورتی که مدام از ابتدای آن حذف کنید، فاجعه‌بار است (O(n)). در حالی که LinkedList این کار را در زمان ثابت (O(1)) انجام می‌دهد. همیشه قبل از انتخاب ابزار، به نحوه دسترسی و تغییر داده‌ها فکر کنید.

۲. مدیریت حافظه (Memory Overhead)

اشیاءِ کالکشن در جاوا "ارزان" نیستند. یک HashMap یا LinkedList به ازای هر گره (Node) مقدار زیادی حافظه اضافی (Overhead) برای نگهداری ریفرنس‌های داخلی مصرف می‌کند. در سیستم‌هایی با رم محدود، گاهی اوقات استفاده از یک آرایه ساده یا کالکشن‌های تخصصیِ Primitive (مثل آنچه در کتابخانه‌های Trove یا FastUtil یافت می‌شود) گزینه‌ی بهتری است.

۳. امنیت نخ (Thread Safety) و کالکشن‌ها

اکثر کالکشن‌های پایه در جاوا (مثل ArrayList و HashMap) Thread-Safe نیستند. یعنی اگر دو نخ (Thread) همزمان سعی کنند در آن‌ها بنویسند، برنامه کراش می‌کند یا داده‌ها خراب می‌شوند. برای محیط‌های چندنخی، باید از ConcurrentHashMap یا کلاس‌های کمکی در Collections.synchronizedList استفاده کرد.

نکته طلایی: در جاوا، همیشه سعی کنید "نوعِ متغیر" را اینترفیس بگیرید و "نوعِ پیاده‌سازی" را کلاس واقعی. مثلاً: List<String> list = new ArrayList<>();. این کار تعویضِ پیاده‌سازی را در آینده بسیار راحت می‌کند.

تمرین‌های عملی

برای تثبیت یادگیری این درس تمرین‌های زیر را حل کنید

دفترچه تلفن کوچک Medium
سوال تمرین

یک HashMap بسازید که نام (String) را به عنوان کلید و شماره (Integer) را به عنوان مقدار بگیرد. مخاطب "Ali" با شماره 123 را اضافه کنید. سپس شماره او را چاپ کنید.

پاسخ تمرین
JAVA
import java.util.HashMap;

public class Main {
  public static void main(String[] args) {
    HashMap<String, Integer> phoneBook = new HashMap<String, Integer>();
    phoneBook.put("Ali", 123);
    System.out.println(phoneBook.get("Ali"));
  }
}

آماده رفتن به درس بعدی هستید؟

این درس را به پایان رساندید و می‌توانید به درس بعدی بروید.