Array List
📖توضیحات درس
📄جزوه
مفاهیم کلیدی
ArrayList
یک ساختار داده در جاوا که پیادهسازی اینترفیس List است و بر پایه آرایهها (Array) ساخته شده است. این ساختار اجازه میدهد لیستی از اشیاء را به صورت پویا ذخیره کنید.
Dynamic Array
آرایهای که قابلیت تغییر سایز دارد. برخلاف آرایههای معمولی که طول ثابت دارند، ArrayList در صورت پر شدن، به طور خودکار یک آرایه بزرگتر (معمولاً دو برابر) ایجاد کرده و عناصر را به آن منتقل میکند.
Ordered Sequence
به این معنا که ArrayList ترتیب ورود عناصر را حفظ میکند و هر عنصر بر اساس زمان اضافه شدن، یک ایندکس مشخص دارد.
Duplicate Elements قابلیتی که به کاربر اجازه میدهد مقادیر تکراری را در لیست ذخیره کند. برای مثال، عدد ۵ میتواند چندین بار در یک لیست قرار بگیرد.
Generics
قابلیتی در جاوا که اجازه میدهد نوع دادههای ذخیره شده در ArrayList را مشخص کنید (مثلاً ArrayList<String>). این کار باعث امنیت تایپی (Type Safety) شده و نیاز به Cast کردن را از بین میبرد.
Zero-based Indexing
مانند آرایههای استاندارد، شمارهگذاری خانهها در ArrayList از صفر شروع میشود.
موارد مصاحبه ای
چرا دسترسی تصادفی (Random Access) در ArrayList دارای مرتبه زمانی O(1) است؟
چون ArrayList از آرایه در لایه زیرین استفاده میکند، با داشتن ایندکس میتوان مستقیماً به آدرس حافظه آن خانه دسترسی پیدا کرد که زمان آن مستقل از حجم لیست است.
در چه شرایطی عملیات add دارای مرتبه زمانی O(n) میشود؟
در حالت عادی اضافه کردن به انتهای لیست O(1) است، اما اگر ظرفیت آرایه پر شده باشد، سیستم باید یک آرایه جدید بسازد و تمام عناصر قبلی را در آن کپی کند که این فرآیند به تعداد عناصر (n) زمان میبرد.
چرا حذف (Delete) یا درج (Insert) در میانه لیست O(n) است؟ زیرا با حذف یا درج یک عنصر در وسط لیست، تمام عناصر بعد از آن ایندکس باید یک واحد به جلو یا عقب جابهجا (Shift) شوند.
تفاوت جستجو در لیست مرتب (Sorted) و نامرتب (Unsorted) چیست؟
در لیست نامرتب باید تمام عناصر را یکییکی چک کرد (O(n))، اما در لیست مرتب میتوان از Binary Search استفاده کرد که با هر مقایسه نیمی از دادهها را کنار میگذارد و سرعت بسیار بالاتری دارد (O(log n)).
چرا بهتر است از اینترفیس List در سمت چپ تعریف متغیر استفاده کنیم؟
مثلاً List<String> list = new ArrayList<>(). این کار یک Best Practice است زیرا کد را منعطف میکند و شما را محدود به یک پیادهسازی خاص نمیکند، بنابراین بعداً راحتتر میتوانید نوع لیست را تغییر دهید.
سناریو کاربردی
در ویدیو، سناریوی مدیریت یک لیست از رشتهها (String) بررسی شد. ابتدا یک ArrayList ساخته شد و عناصری مثل "A" و "B" و "C" به آن اضافه شدند.
سپس مدرس نشان داد که چگونه میتوان با استفاده از متد add(index, value) یک عنصر جدید مثل "A1" را دقیقاً در ایندکس ۱ (بین A و B) تزریق کرد. در این مرحله توضیح داده شد که برای باز شدن جا برای "A1"، عناصر بعدی در حافظه جابهجا میشوند.
همچنین در سناریوی حذف، استفاده از indexOf برای پیدا کردن مکان یک شیء و سپس فراخوانی remove برای حذف آن نمایش داده شد، با این تاکید که اگر شیء تکراری باشد، indexOf اولین مورد و lastIndexOf آخرین مورد را پیدا میکند.
بیشتر بدانید
نکته بهینهسازی (Initial Capacity)
اگر میدانید قرار است تعداد زیادی داده (مثلاً ۱۰۰۰ مورد) در لیست بریزید، از ابتدا ظرفیت را در سازنده مشخص کنید: new ArrayList<>(1000). این کار از چندین بار تغییر سایز خودکار و کپی شدن آرایه که هزینه پردازشی بالایی دارد، جلوگیری میکند.
IDE Tip
در محیط IntelliJ، هنگام فراخوانی یک متد یا سازنده، با فشردن کلیدهای Ctrl + P میتوانید لیست پارامترهای ورودی و اورلودهای (Overloads) مختلف آن متد را مشاهده کنید.
متد سایز
برای به دست آوردن تعداد عناصر موجود در ArrayList همیشه از متد size() استفاده میشود، نه length (که مخصوص آرایههای ساده است).
حذف مستقیم آبجکت
متد remove اورلود شده است؛ یعنی هم میتوانید ایندکس بدهید و هم خودِ آبجکت را مستقیماً پاس بدهید تا جاوا خودش آن را پیدا کرده و حذف کند.
