JavaRush /وبلاگ جاوا /Random-FA /10 سوال برتر درباره مجموعه ها در جاوا
FedoraLinux
مرحله
Москва

10 سوال برتر درباره مجموعه ها در جاوا

در گروه منتشر شد
این مقاله ترجمه ای از مقاله 10 سوال برتر در مورد مجموعه های جاوا می باشد . در زیر محبوب‌ترین سؤالات درباره مجموعه‌ها در جاوا وجود دارد که در Stackowerflow پرسیده شده و مورد بحث قرار گرفته است. قبل از اینکه به این سؤالات نگاه کنید، خوب است که به نمودار سلسله مراتب کلاس نگاه کنید. 1. چه زمانی به جای ArrayList از LinkedList استفاده کنیم؟ یک ArrayList در واقع یک آرایه است؛ عناصر آن را می توان مستقیماً از طریق فهرست دسترسی داشت. اگر آرایه سرریز شود، آرایه جدیدی با فضای بیشتر ضروری می شود. قرار دادن و جابجایی همه عناصر به زمان O(n) نیاز دارد. همچنین افزودن و حذف عناصر برای جابجایی عناصر موجود در آرایه ضروری است. این شاید بزرگترین ناراحتی استفاده از ArrayList باشد. LinkedList یک لیست دوگانه از پیوندهای عنصر است. بنابراین، برای دسترسی به عنصر در مرکز، باید از ابتدا تا انتهای برگه را جستجو کنید. از طرف دیگر، افزودن و حذف یک عنصر در LinkedList سریعتر است زیرا این عملیات فقط خود لیست را تغییر می دهد. بدترین زمان ها در زیر مقایسه شده اند:
روش فهرست آرایه LinkedList
دریافت (شاخص) O (1) بر)
افزودن (E) بر) O (1)
افزودن (E، نمایه) بر) بر)
حذف (شاخص) بر) بر)
Iterator.remove() بر) O (1)
Iterator.add(E) بر) O (1)
با وجود زمان اجرا، استفاده از حافظه باید به صورت جداگانه برای لیست های بزرگ در نظر گرفته شود. در یک LinkedList، هر گره باید حداقل دو اشاره گر اضافی برای پیوند دادن گره های قبلی و بعدی داشته باشد، در حالی که در یک ArrayList، فقط یک آرایه از عناصر مورد نیاز است. مقایسه‌های بیشتر فهرست‌های ArrayList، LinkedList و Vector . 2. معادل کارآمد برای حذف عناصر در طول تکرار مجموعه تنها راه صحیح برای اصلاح (حذف عناصر) یک مجموعه در طول تکرار استفاده از Iterator.remove() است . به عنوان مثال: رایج ترین خطا این است: هنگام اجرای کد بالا یک ConcurrentModificationException دریافت خواهید کرد . این به این دلیل اتفاق می‌افتد که تکرارکننده برای حرکت در کل لیست ایجاد شده است، اما در همان زمان با فراخوانی Iterator.remove() شیت تغییر می‌کند. همانطور که در اسناد این استثنا نوشته شده است، Iterator itr = list.iterator(); while(itr.hasNext()) { // do something itr.remove(); } for(Integer i: list) { list.remove(i); }
"به طور کلی مجاز نیست که یک رشته یک مجموعه را تغییر دهد در حالی که رشته دیگری روی آن تکرار می شود."
به طور کلی، این غیرقابل قبول است که یک رشته یک مجموعه را تغییر دهد در حالی که رشته دیگری در حال عبور از آن است. 3. چگونه لیست را به آرایه int[] تبدیل کنیم؟ ساده ترین راه برای انجام این کار استفاده از ArrayUtils است که در کتابخانه Apache Commons Lang قرار دارد . int[] array = ArrayUtils.toPrimitive(list.toArray(new Integer[0])); هیچ میانبری برای این عبارت در JDK وجود ندارد. به یاد داشته باشید که نمی توانید از List.toArray() استفاده کنید زیرا این عبارت List را به عدد صحیح[] (که یک نوع اولیه نیست ) تبدیل می کند. راه صحیح گزینه زیر خواهد بود: int[] array = new int[list.size()]; for(int i=0; i < list.size(); i++) { array[i] = list.get(i); } 4. چگونه یک آرایه int[] را به لیست تبدیل کنیم؟ ساده ترین راه نیز استفاده از ArrayUtils در کتابخانه Apache Commons Lang است ، مانند بالا. List list = Arrays.asList(ArrayUtils.toObject(array)); همچنین هیچ میانبری برای این عبارت در JDK وجود ندارد. 5. بهترین راه برای فیلتر کردن مجموعه چیست؟ برای افزایش عملکرد می توانید از بسته های شخص ثالث مانند Guava یا Apache Commons Lang استفاده کنید. هر دوی این بسته ها دارای یک متد filter() هستند (در کلاس Collections2 از Guava و CollectionUtils از Apache). متد filter() عناصری را برمی گرداند که با Predicate داده شده مطابقت دارند. در JDK همه چیز پیچیده تر است. خبر خوب این است که گزاره ها در جاوا 8 اضافه خواهند شد ، اما در حال حاضر باید از Iterator برای تکرار در کل مجموعه استفاده کنید. البته می توانید با آشنایی با رابط جدید Predicate مسیری را که Guava و Apache دنبال می کنند تقلید کنید. اکنون می توانیم از کد زیر برای فیلتر کردن مجموعه استفاده کنیم: 6. چگونه لیست را به راحتی به Set تبدیل کنیم؟ بسته به اینکه چگونه می خواهید برابری را تعریف کنید، دو راه برای انجام این کار وجود دارد. اولین قطعه کد لیست را در یک HashSet قرار می دهد. تکراری در این مورد عمدتا توسط hashCode() تعیین می شود. به طور معمول این کار خواهد کرد. اما اگر باید مسیر مقایسه را در نظر بگیرید، بهتر است از قسمت دوم کد استفاده کنید، جایی که می توانید مقایسه کننده خود را تعریف کنید. 7. چگونه می توانم عناصر تکراری را از ArrayList حذف کنم؟ این سوال تا حدودی با سوال بالا مرتبط است. اگر ترتیب عناصر موجود در ArrayList برای شما مهم نیست، یک حرکت هوشمندانه این است که برگه را در یک مجموعه قرار دهید تا موارد تکراری حذف شود و سپس آن را به لیست برگردانید. در زیر یک نمونه آورده شده است. اگر ترتیب عناصر برای شما مهم است، می توانید با قرار دادن لیست در LinkedHashSet که در JDK استاندارد است، از ترتیب آن اطمینان حاصل کنید. 8. مجموعه مرتب شده int[] array = {1,2,3,4,5}; List list = new ArrayList (); for(int i: array) { list.add(i); } Iterator itr = list.iterator(); while(itr.hasNext()) { int i = itr.next(); if (i > 5) { // filter all ints bigger than 5 itr.remove(); } } public interface Predicate { boolean test(T o); } public static void filter(Collection collection, Predicate predicate) { if ((collection != null) && (predicate != null)) { Iterator itr = collection.iterator(); while(itr.hasNext()) { T obj = itr.next(); if (!predicate.test(obj)) { itr.remove(); } } } } filter(list, new Predicate () { public boolean test(Integer i) { return i <= 5; } }); Set set = new HashSet (list); Set set = new TreeSet (aComparator); set.addAll(list); ArrayList** list = ... // initial a list with duplicate elements Set set = new HashSet (list); list.clear(); list.addAll(set); راه های مختلفی برای پشتیبانی از یک مجموعه مرتب شده در جاوا وجود دارد. همه آنها مجموعه ای را به ترتیب طبیعی یا توسط یک مقایسه کننده مشخص ارائه می دهند. در مورد نظم طبیعی، همچنین باید رابط Comparable را روی عنصر پیاده سازی کنید.
  1. Collections.sort() می تواند یک لیست را مرتب کند. همانطور که در مستندات جاوا بیان شد، این مرتب سازی پایدار است و عملکرد n log(n) را تضمین می کند.
  2. PriorityQueue یک صف منظم فراهم می کند. تفاوت بین PriorityQueue و Collections.sort() این است که PriorityQueue مرتباً ترتیب صف را حفظ می کند، اما شما فقط می توانید اولین عنصر صف را دریافت کنید. شما نمی توانید به طور تصادفی به عنصری مانند PriorityQueue.get(4) دسترسی پیدا کنید.
  3. اگر هیچ مورد تکراری در مجموعه وجود ندارد، می توانید TreeSet را انتخاب کنید . همچنین مانند PriorityQueue، TreeSet یک مجموعه مرتب را همیشه حفظ می کند. شما می توانید کوچکترین یا بزرگترین عنصر را از یک TreeSet دریافت کنید، اما هنوز نمی توانید به طور تصادفی به عناصر دسترسی داشته باشید.
به عبارت ساده، Collections.sort() یک لیست مرتب شده یک بار ارائه می دهد. PriorityQueue و TreeSet یک مجموعه مرتب شده را همیشه حفظ می کنند، به قیمت عدم دسترسی فهرست شده به عناصر. 9. Collections.emptyList() یا نمونه جدید همین سوال در مورد()veneMap و()emptyList صدق می کند. هر دو روش یک لیست خالی برمی گرداند، اما Collections.emptyList() یک لیست تغییرناپذیر است. این بدان معنی است که شما نمی توانید عناصر جدیدی را به یک لیست "خالی" اضافه کنید. در پس‌زمینه، هر فراخوانی به متد Collections.emptyList () در واقع یک نمونه جدید از لیست خالی ایجاد نمی‌کند. در عوض، از نمونه خالی موجود مجددا استفاده خواهد کرد. اگر با Singleton به عنوان یک الگوی طراحی آشنا هستید ، باید منظور را درک کنید. در صورت تماس مکرر، این باید عملکرد بهتری به شما بدهد . 10 کپی کردن یک مجموعه، Collections.copy() دو راه برای کپی کردن یک لیست منبع در لیست مقصد وجود دارد. یکی از راه ها استفاده از سازنده ArrayList است. راه دیگر استفاده از متد Collections.copy() است . توجه داشته باشید در خط اول: ما لیستی را اختصاص می دهیم که حداقل طول آن به اندازه طول لیست اصلی باشد، زیرا مستندات جاوا درباره مجموعه ها می گوید: ArrayList dstList = new ArrayList (srcList);
فهرست مقصد باید حداقل به اندازه فهرست مبدا باشد.
به این معنی که لیست نهایی نباید کوتاهتر از لیست اصلی باشد. هر دو روش کپی سطحی هستند. پس تفاوت این دو روش چیست؟ اول، Collections.copy () ظرفیت مجموعه dstList را دوباره تخصیص نمی دهد، حتی اگر dstList فضای کافی برای حاوی تمام عناصر srcList نداشته باشد. در عوض، IndexOutOfBoundsException را پرتاب می کند . ممکن است کسی بپرسد که آیا این کار فایده ای دارد؟ دلیل آن این است که این تضمین می کند که روش به صورت خطی در زمان اجرا می شود. این همچنین زمانی مناسب است که بخواهید از آرایه ها به جای تخصیص مجدد حافظه در سازنده ArrayList استفاده کنید. به جای نتیجه گیری اگر پس از خواندن مقاله هنوز سؤالی دارید، در نظرات بپرسید. همچنین در صورت مشاهده هر گونه اشتباه در ترجمه یا هر گونه ایراد دیگری به PM بنویسید اصلاح می شود و از شما تشکر می شود. اصل. ArrayList dstList = new ArrayList (srcList.size()); Collections.copy(dstList, srcList);
نظرات
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION