معرفی Collections Framework
Collections Framework پرکاربردترین API در JDK است. هر اپلیکیشنی که روی آن کار میکنید، به احتمال زیاد در نقطهای نیاز دارد دادهها را در حافظه ذخیره و پردازش کند.
تاریخچهی ساختمانهای داده (Data Structures) تقریباً به اندازهی خود محاسبات قدمت دارد. Collections Framework پیادهسازی مفاهیمی است دربارهی نحوهی ذخیره، سازماندهی و دسترسی به دادهها در حافظه که مدتها قبل از اختراع جاوا توسعه یافته بودند. Collections Framework این کار را به شیوهی بسیار کارآمدی انجام میدهد — همانطور که خواهید دید.
Collections Framework برای اولین بار در Java SE 2، در سال ۱۹۹۸ معرفی شد و از آن زمان دو بار بازنویسی شده است:
- در Java SE 5 وقتی Generics اضافه شد؛
- در Java 8 وقتی Lambda Expressionها و متدهای Default در Interfaceها معرفی شدند.
این دو مهمترین بهروزرسانیهای Collections Framework تا به امروز هستند. اما در واقع، تقریباً هر نسخه از JDK مجموعهی تغییرات خود را در Collections Framework دارد.
در این بخش، مفیدترین ساختمانهای دادهای که Collections Framework ارائه میدهد را یاد میگیرید، همراه با الگوهایی که برای دستکاری این دادهها در اپلیکیشنتان استفاده خواهید کرد.
اولین چیزی که باید بدانید این است که از دیدگاه فنی، Collections Framework مجموعهای از Interfaceها است که روشهای مختلف ذخیرهی داده در انواع مختلف Containerها را مدلسازی میکند. سپس Framework حداقل یک پیادهسازی برای هر Interface فراهم میکند. شناخت این پیادهسازیها به اندازهی خود Interfaceها مهم است و انتخاب پیادهسازی صحیح به این بستگی دارد که میخواهید با آن چه کاری انجام دهید.
---یافتن مسیر در Collections Framework
تعداد Interfaceها و کلاسها در Collections Framework ممکن است در ابتدا سردرگمکننده باشد. واقعاً ساختمانهای زیادی موجود است، هم کلاس و هم Interface. بعضی اسامی گویایی دارند مثل LinkedList، بعضی رفتار مشخصی دارند مثل ConcurrentHashMap و بعضی شاید عجیب به نظر برسند مثل ConcurrentSkipListMap.
شما از بعضی از این عناصر بسیار بیشتر از بقیه استفاده خواهید کرد. اگر از قبل با زبان جاوا آشنا هستید، احتمالاً با List، ArrayList و Map برخورد کردهاید. این آموزش روی پرکاربردترین ساختمانهای Collections Framework تمرکز دارد — همانهایی که بهعنوان یک توسعهدهندهی جاوا روزانه از آنها استفاده خواهید کرد و باید بهتر آنها را بشناسید و درک کنید.
با این وجود، باید تصویر کلی از آنچه در Collections Framework وجود دارد داشته باشید.
اول از همه، Framework از Interfaceها و پیادهسازیها تشکیل شده است. انتخاب Interface صحیح به این معناست که باید بدانید چه توابعی میخواهید به اپلیکیشنتان اضافه کنید. اگر نیاز شما شامل یکی از این موارد است:
- ذخیرهی اشیاء و حلقهزدن روی آنها؟
- قرار دادن شیتان در یک صف و خارج کردن آنها؟
- بازیابی آنها با استفاده از یک کلید؟
- دسترسی به آنها از طریق ایندکس؟
- مرتب کردن آنها؟
- جلوگیری از وجود مقادیر تکراری یا مقادیر null؟
انتخاب پیادهسازی صحیح به این معناست که باید بدانید چگونه از این قابلیتها استفاده خواهید کرد:
- آیا دسترسی به اشیاء از طریق حلقهزدن انجام میشود یا دسترسی تصادفی و ایندکسدار؟
- آیا اشیاء هنگام راهاندازی اپلیکیشن ثابت هستند و در طول عمر آن تغییر زیادی نمیکنند؟
- آیا تعداد زیادی شیء ذخیره میکنید؟ آیا نیاز دارید برای وجود بعضی اشیاء خاص بهکرات بررسی کنید؟
- آیا ساختمانی که اشیاء را در آن ذخیره میکنید باید بهصورت همزمان (Concurrently) قابل دسترسی باشد؟
Collections Framework میتواند راهحل مناسبی برای همهی این مشکلات به شما بدهد.
دو دستهی اصلی Interface در Collections Framework وجود دارد: collections و maps.
Collections دربارهی ذخیرهی اشیاء و حلقهزدن روی آنها هستند. Interface Collection ریشهی این دسته است. در واقع Interface Collection از Interface Iterable ارثبری میکند، اما این Interface بخشی از Collections Framework نیست.
Map یک شیء را همراه با یک کلید ذخیره میکند که آن شیء را نمایندگی میکند، دقیقاً مثل کلید اولیه (Primary Key) در یک پایگاه داده — اگر با این مفهوم آشنا باشید. گاهی میشنوید که maps جفتهای key/value ذخیره میکنند که دقیقاً توصیف میکند map چه کاری انجام میدهد. Interface Map ریشهی این دسته است.
هیچ رابطهی مستقیمی بین Interfaceهای سلسلهمراتبی Collection و سلسلهمراتبی Map وجود ندارد.
علاوه بر این collections و maps، باید بدانید که Interfaceهایی برای مدلسازی صفها (Queues) و پشتهها (Stacks) نیز در سلسلهمراتب Collection وجود دارد. صفها و پشتهها واقعاً دربارهی حلقهزدن روی مجموعهی اشیاء نیستند، اما چون به سلسلهمراتب Collection اضافه شدهاند، مشخص شده که میتوانید این کار را با آنها انجام دهید.
یک سلسلهمراتب دیگر هم وجود دارد که باید بشناسید و آن سلسلهمراتب Iterator است. Iterator شیئی است که میتواند روی مجموعهای از اشیاء حلقه بزند و بخشی از Collections Framework است.
پس دو دستهی اصلی داریم (Collection و Map)، یک زیردسته (Queue) و یک دستهی جانبی (Iterator).
اجتناب از استفاده از Interfaceها و پیادهسازیهای قدیمی
Collections Framework فقط در Java 2 معرفی شد، یعنی زندگی قبل از آن هم وجود داشته. این زندگی شامل چندین کلاس و Interface است که هنوز در JDK هستند — برای حفظ سازگاری معکوس (Backward Compatibility) — اما دیگر نباید در اپلیکیشنهایتان از آنها استفاده کنید.
این کلاسها و Interfaceها عبارتند از:
VectorوStack. کلاسVectorبرای پیادهسازی InterfaceListبازسازی شده. اگر در محیطی غیر همزمان (Non-concurrent) از Vector استفاده میکنید، میتوانید آن را باArrayListجایگزین کنید. کلاسStackازVectorارثبری میکند و باید در محیطهای غیر همزمان باArrayDequeجایگزین شود.- کلاس
Vectorاز InterfaceEnumerationبرای مدلسازی iterator خود استفاده میکند. دیگر نباید از این Interface استفاده شود: Interface ترجیحی اکنونIteratorاست. Hashtable: این کلاس برای پیادهسازی InterfaceMapبازسازی شده. اگر از نمونههای این کلاس در محیط غیر همزمان استفاده میکنید، میتوانید آن را باHashMapجایگزین کنید. در محیط همزمان،ConcurrentHashMapمیتواند جایگزین مناسبی باشد.
چرا Collection را بر Array ترجیح دهیم؟
شاید از خودتان بپرسید چرا باید زحمت یادگیری Collections Framework را بکشید، وقتی ممکن است احساس کنید قرار دادن دادهها در یک array قدیمی خوب کار میکند.
واقعیت این است که اگر راهحلی ساده، تسلطیافته و متناسب با نیازهایتان دارید، حتماً به همان پایبند باشید!
چه کاری یک collection میتواند برای شما انجام دهد که یک array نمیتواند؟
- یک collection تعداد عناصر خود را ردیابی میکند
- ظرفیت یک collection نامحدود است: میتوانید (تقریباً) هر تعداد عنصر به یک collection اضافه کنید
- یک collection میتواند کنترل کند چه عناصری را میتوانید در آن ذخیره کنید. مثلاً میتوانید از اضافه شدن عناصر null جلوگیری کنید
- یک collection را میتوان برای وجود یک عنصر خاص پرسش کرد
- یک collection عملیاتی مثل اشتراک یا ادغام با collection دیگر ارائه میدهد
این فقط نمونهی کوچکی از کارهایی است که یک collection میتواند برای شما انجام دهد. در واقع، چون collection یک شیء است و هر شیئی قابل توسعه است، میتوانید هر عملیاتی که نیاز دارید به بیشتر collectionهای JDK اضافه کنید. با array این کار امکانپذیر نیست.
این محتوا کاملا رایگان توسط تیم کدلپر ترجمه شده و در اختیار شما کاربران عزیز قرار گرفته است، هر گونه کپی برداری برای مقاصد غیر رایگان و بدون ذکر منبع، مورد پیگیری قانونی قرار میگیرد.
ترجمه شده از منبع: منبع مستندات