دوره‌ها / JAVA / تکرارگرها (Java Iterator)

تکرارگرها (Java Iterator)

15 دقیقه Article

تکرارگرها (Iterator): روشِ امنِ پیمایش 🔄🚶

Iterator یک شیء است که می‌توان از آن برای پیمایش (Loop) در کالکشن‌ها (مثل ArrayList یا HashSet) استفاده کرد. در واقع این متمدن‌ترین و ایمن‌ترین راه برای چرخیدن در میانِ داده‌هاست.

۱. چرا به Iterator نیاز داریم؟

شاید بپرسید "مگر حلقه for-each چه ایرادی دارد؟". مشکل زمانی پیش می‌آید که بخواهید در حینِ چرخیدن در یک لیست، گزینه‌ای را حذف کنید. اگر در حلقه معمولی این کار را بکنید، جاوا خطای ConcurrentModificationException می‌دهد و برنامه متوقف می‌شود. Iterator تنها راهِ حذفِ امنِ داده در حین پیمایش است.

۲. نحوه استفاده 🛠️

هر کالکشنی متدی به نام iterator() دارد که این شیء را به شما می‌دهد:

{code_block('Iterator<String> it = cars.iterator();\nwhile(it.hasNext()) {\n System.out.println(it.next());\n}')}

۳. متدهای اصلی

  • hasNext(): آیا آیتم دیگری وجود دارد؟ (خروجی true/false).
  • next(): آیتم بعدی را بده و برو جلو.
  • remove(): آیتم فعلی را از کالکشن اصلی حذف کن.

فیلتر کردن لیست:

{code_block('while(it.hasNext()) {\n Integer i = it.next();\n if(i < 10) { it.remove(); } // حذف تمام اعداد کوچکتر از 10\n}')}
تک جهته: ایتراتور معمولی فقط رو به جلو می‌رود. اگر نیاز دارید به عقب هم برگردید، باید از ListIterator (مخصوصِ لیست‌ها) استفاده کنید.
نکته طراحی: ایتراتورها پیاده‌سازیِ الگوی طراحی Iterator Pattern هستند که باعث می‌شود کد شما به نوعِ کالکشن وابسته نباشد.
<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
سوال تمرین

یک لیست شامل "A", "B", "C" دارید. با استفاده از Iterator، تمام اعضا را چاپ کنید.

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

public class Main {
  public static void main(String[] args) {
    ArrayList<String> list = new ArrayList<String>(Arrays.asList("A", "B", "C"));
    Iterator<String> it = list.iterator();
    while (it.hasNext()) {
      System.out.println(it.next());
    }
  }
}

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

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