
مجموعه ها
84. در مورد تکرار کننده ها و نحوه استفاده از آنها بگویید
مجموعه ها یک موضوع مورد علاقه در هر مصاحبه توسعه دهنده جاوا است. هنگام پاسخ به سؤالات مربوط به سلسله مراتب مجموعه، نامزدها اغلب می گویند که با رابط مجموعه شروع می شود . اما این طوری نیست. رابط دیگری در یک سطح بالاتر وجود دارد: تکرارپذیر . این رابط از متد iterator() تشکیل شده است که به شما امکان می دهد به شی Iterator برای مجموعه فعلی دسترسی داشته باشید. و این شی Iterator دقیقا چیست ؟ شی Iterator توانایی حرکت در یک مجموعه و تکرار بر روی عناصر آن را فراهم می کند و کاربر نیازی به دانستن جزئیات پیاده سازی خاص مجموعه ندارد. به عبارت دیگر، نوعی اشاره به عناصر مجموعه است، گویی در درون یکی از آنها را زیر نظر می گیرد. تکرار کننده روش هایی مانند:-
hasNext() - اگر تکرار عنصر دیگری داشته باشد، true را برمیگرداند (این روش به شما امکان میدهد بدانید چه زمانی به پایان مجموعه رسیدید).
-
next() - مورد بعدی را در تکرار برمی گرداند. اگر یکی نباشد، یک NoSuchElementException پرتاب می شود. این بدان معناست که قبل از استفاده از این روش، بهتر است از متد hasNext() استفاده کنید تا مطمئن شوید عنصر بعدی وجود دارد.
-
remove() — آخرین عنصر دریافتی را با استفاده از متد next() از مجموعه حذف می کند . اگر next() هرگز فراخوانی نشده باشد، فراخوانی remove() باعث می شود که یک IllegalStateException پرتاب شود.
-
forEachRemaining(<Consumer>) - عمل تصویب شده را روی هر عنصر مجموعه اجرا می کند (این روش در جاوا 8 ظاهر شد).
List<String> list = new ArrayList<>();
list.add("Hello ");
list.add("World, ");
list.add("It's ");
list.add("Amigo!");
Iterator iterator = list.iterator();
while(iterator.hasNext()) {
iterator.next();
iterator.remove();
}
System.out.println(list.size());
کنسول موارد زیر را نمایش می دهد:
iterator.forEachRemaining(x -> System.out.print(x));
اما وقتی این کار را انجام دهیم، تکرار کننده برای استفاده بیشتر نامناسب می شود: کل لیست را طی کرده است، و یک تکرار کننده معمولی هیچ روشی برای تکرار به عقب ندارد. و این باعث می شود که بحث خوبی در بحث LinkedList ایجاد شود، به ویژه، متد listIterator() آن ، که نوع پیشرفته ای از تکرارکننده را برمی گرداند: ListIterator . این نوع علاوه بر روش های تکرار کننده معمولی (استاندارد) دارای موارد زیر است:
-
add(<Element>) - یک عنصر جدید به لیست اضافه می کند.
-
hasPrevious() - اگر عنصری قبل از عنصر بعدی باشد (اگر عنصر قبلی وجود داشته باشد) true را برمی گرداند.
-
nextIndex() - شاخص عنصر بعدی را برمی گرداند.
-
previous() - عنصر قبلی (یکی قبل از عنصر بعدی) را برمی گرداند.
-
previousIndex شاخص عنصر قبلی را برمی گرداند.
-
set(<Element>) - جایگزین آخرین عنصر بازگشتی توسط next() یا previous() می شود .

85. چه سلسله مراتبی در مجموعه Java Framework وجود دارد؟
دو سلسله مراتب مجموعه در جاوا وجود دارد. اولین سلسله مراتب ، سلسله مراتب مجموعه است که ساختار زیر را دارد:
-
مجموعه یک رابط است که یک مجموعه را توصیف می کند، یک ساختار داده ای که شامل عناصر منحصر به فرد (غیر تکراری) نامرتب است. این رابط پیاده سازی استاندارد دارد: TreeSet ، HashSet و LinkedHashSet .
-
لیست یک رابط است که ساختار داده ای را توصیف می کند که دنباله ای مرتب از اشیاء را ذخیره می کند. اشیاء در یک لیست را می توان با فهرست آنها در لیست درج و حذف کرد (مانند یک آرایه، اما با تغییر اندازه پویا). این رابط پیاده سازی استاندارد نیز دارد: ArrayList ، Vector ( منسوخ شده و در واقع استفاده نشده است )، و LinkedList .
-
Queue رابطی است که یک ساختار داده را توصیف می کند که موارد را در صف First In First Out (FIFO) ذخیره می کند . این رابط پیادهسازیهای استاندارد زیر را دارد: LinkedList (درست است، Queue را نیز پیادهسازی میکند ) و PriotityQueue .


86. ساختار داخلی ArrayList چیست؟
ArrayList مانند یک آرایه است، اما می تواند به صورت پویا گسترش یابد . معنی آن چیست؟ در زیر هود، ArrayList از یک آرایه معمولی استفاده می کند، یعنی عناصر خود را در یک آرایه داخلی ذخیره می کند که اندازه پیش فرض آن 10 سلول است. پس از پر شدن آرایه داخلی، یک آرایه جدید ایجاد می شود. اندازه آرایه جدید با این فرمول تعیین می شود:<size of the current array> * 3 / 2 + 1
بنابراین، اگر اندازه آرایه ما 10 باشد، اندازه آرایه جدید خواهد بود: 10 * 3 / 2 + 1 = 16. سپس تمام مقادیر آرایه اصلی (قدیمی) با استفاده از داخلی در آن کپی می شوند. متد System.arraycopy() و آرایه اصلی حذف می شود. به طور خلاصه، ArrayList اینگونه است که تغییر اندازه پویا را پیاده سازی می کند. بیایید محبوبترین روشهای ArrayList را در نظر بگیریم : 1. add(<Element>) - یک عنصر را به انتهای آرایه (در آخرین سلول خالی) اضافه میکند، پس از اینکه ابتدا بررسی کرد که آیا یک سلول موجود در آرایه وجود دارد یا خیر. اگر نه، یک آرایه جدید ایجاد می شود و عناصر در آن کپی می شوند. پیچیدگی زمانی این عملیات O(1) است. یک روش مشابه add(<Index>, <Elelement>) وجود دارد . یک عنصر را نه به انتهای لیست (آرایه)، بلکه به سلول خاصی که با شاخصی که به عنوان آرگومان وارد شده است، اضافه می کند. در این مورد، پیچیدگی زمانی بسته به جایی که اضافه میکنید متفاوت خواهد بود:
- اگر افزودن نزدیک به ابتدای لیست باشد، پیچیدگی زمانی نزدیک به O(N) خواهد بود، زیرا تمام عناصر واقع در سمت راست مورد جدید باید یک سلول به سمت راست منتقل شوند.
- اگر عنصر در وسط درج شود، آنگاه O(N/2) خواهد بود، زیرا فقط باید نیمی از موارد لیست را یک سلول به سمت راست منتقل کنیم.
87. ساختار داخلی LinkedList چیست؟
یک ArrayList حاوی عناصری در آرایه داخلی است، اما یک LinkedList آنها را در یک لیست دارای پیوند دوگانه ذخیره می کند. این بدان معنی است که هر عنصر حاوی پیوندی به عنصر قبلی و عنصر بعدی است . عنصر اول به عنصر قبلی پیوند نمی خورد (در نهایت، اولین عنصر است). همچنین به عنوان سر لیست در نظر گرفته می شود و شی LinkedList یک ارجاع مستقیم به آن دارد. به طور مشابه، آخرین عنصر عنصر بعدی را ندارد، زیرا دم لیست است. شی LinkedList نیز مستقیماً به آن ارجاع می دهد. این بدان معنی است که پیچیدگی زمانی دسترسی به سر یا دم یک لیست O(1) است.

- اگر به سر یا دم نزدیک باشد، عملیات به O(1) نزدیک می شود، زیرا عملاً نیازی به تکرار بر روی عناصر نخواهد بود.
- اگر نزدیک به وسط باشد، O(N/2) خواهیم داشت، زیرا این روش از سر و دم به طور همزمان جستجو می کند تا عنصر مورد نظر پیدا شود.

88. ساختار داخلی HashMap چیست؟
این ممکن است یکی از پرطرفدارترین سوالات مصاحبه ای باشد که باید از نامزدهای توسعه دهنده جاوا پرسیده شود. HashMap با جفت های کلید-مقدار کار می کند . چگونه آنها در داخل خود HashMap ذخیره می شوند ؟ HashMap دارای یک آرایه داخلی از گره ها است :Node<K,V>[] table
بهطور پیشفرض، اندازه آرایه 16 است و هر بار که با عناصر پر میشود، دو برابر میشود (یعنی وقتی به LOAD_FACTOR رسید ؛ آستانه پر شدن آرایه را مشخص میکند - به طور پیشفرض، 0.75 است ). . هر یک از گره ها یک هش از کلید، کلید، یک مقدار و یک ارجاع به عنصر بعدی را ذخیره می کند: 
- سلول خالی است - در این مورد، مقدار Node جدید در آن ذخیره می شود.
- سلول خالی نیست - در این مورد، مقادیر کلیدها با هم مقایسه می شوند. اگر برابر باشند، مقدار Node جدید مقدار قبلی را بازنویسی می کند. اگر مساوی نباشد، سپس به بعدی دسترسی پیدا میکند، و کلید آن مقایسه میشود... و به همین ترتیب، تا زمانی که مقدار جدید مقداری قدیمی را بازنویسی کند یا به انتهای فهرست پیوندی منفرد برسیم و سپس مقدار جدید را در آنجا ذخیره کنیم. آخرین عنصر

GO TO FULL VERSION