89. ArrayList چه تفاوتی با LinkedList دارد؟
این یکی از پرطرفدارترین سوالات به همراه سوال در مورد ساختار داخلی HashMap است . حتی یک مصاحبه بدون آن کامل نیست، و بنابراین پاسخ به آن باید «از دندان شما بیرون بزند». علاوه بر آشکار - نام های مختلف - آنها در ساختار داخلی متفاوت هستند. قبلا ساختار داخلی هر دو ArrayList و LinkedList را بررسی کردیم ، بنابراین به جزئیات پیاده سازی آنها نمی پردازم. فقط به شما یادآوری می کنم که ArrayList بر اساس یک آرایه داخلی پیاده سازی شده است که در صورت نیاز طبق فرمول افزایش می یابد:<размерТекущегоМассива> * 3 / 2 + 1
در همان زمان، LinkedList بر اساس یک لیست داخلی با پیوند دوگانه پیاده سازی می شود، یعنی هر عنصر دارای پیوندی به قبلی و بعدی است، به استثنای مقادیری که ابتدا / انتهای لیست هستند. مردم دوست دارند این سوال را در قالب بپرسند: "کدامیک بهتر است - ArrayList یا LinkedList ؟"، به امید اینکه شما را جلب کنند. به هر حال، اگر به یکی از آنها به عنوان پاسخ اشاره کنید، پاسخ اشتباه خواهد بود. در عوض، باید مشخص کنید که در مورد چه وضعیت خاصی صحبت می کنید - دسترسی به فهرست یا درج در وسط یک لیست. بسته به پاسخ، می توانید انتخاب خود را توضیح دهید. من قبلا توضیح داده ام که ArrayList و LinkedList در یک موقعیت یا موقعیت دیگر چگونه کار می کنند. بیایید این را با قرار دادن آنها در همان صفحه برای مقایسه خلاصه کنیم: افزودن یک عنصر (افزودن)
-
Добавление нового element без указания индекса How местоположения будет происходить автоматически в конец обоих списков. В LinkedList новый элемент станет новым хвостом (происходит только перезаписывание пары ссылок — алгоритмическая сложность O(1)).
В ArrayList будет добавлен новый элемент в последнюю пустую ячейку массива — O(1).
-
Добавление element по индексу How правило подразумевает вставку примерно в середину списка. В LinkedList сперва будет вестись поиск нужного места с помощью перебора элементов с “хвоста” и “головы” — O(n/2), а после — вставка значения путем переопределения ссылок элементов, между которыми вставляется новый — O(1). Суммарная алгоритмическая сложность данного действия будет O(n/2).
ArrayList в данной ситуации по индексу находит элемент — O(1), и все элементы справа (включая элемент, который уже хранится по данному индексу) двигаются на одну единицу вправо (при этом возможно понадобится создание нового списка и копирование элементов в него) — O(n/2). Суммарная сложность — O(n/2). -
Добавление element в начало списка в LinkedList будет ситуация схожая с добавлением в конец: новый элемент станет новой “головой” — O(1), в то же время когда ArrayList-у нужно будет двигать все элементы вправо — O(n).
90. ArrayList چه تفاوتی با HashSet دارد؟
اگر بتوان ArrayList و LinkedList را از نظر عملیات مقایسه کرد - که بهتر است - مقایسه ArrayList با HashSet چندان آسان نیست ، زیرا اینها مجموعه های کاملاً متفاوتی هستند. می توانید یک غذای شیرین را با دیگری مقایسه کنید، اما با یک غذای گوشتی کار می کند - آنها بسیار متفاوت هستند. با این حال، سعی می کنم تفاوت هایی را بین آنها بیان کنم:-
ArrayList رابط List را پیاده سازی می کند ، در حالی که HashSet رابط Set را پیاده سازی می کند .
-
در ArrayList، دسترسی با شاخص عنصر امکان پذیر است: عملیات get دارای پیچیدگی الگوریتمی O(1) است و در HashSet عنصر مورد نیاز را فقط می توان با نیروی brute به دست آورد و این از O(1) تا O(n) است. ;
-
ArrayList اجازه می دهد تا عناصر تکراری. در HashSet، همه عناصر منحصر به فرد هستند: افزودن یک عنصر به HashSet که آنالوگ آن از قبل در مجموعه موجود است کار نخواهد کرد (تکراری ها با استفاده از کد هش بررسی می شوند، از این رو نام این مجموعه است).
-
ArrayList با استفاده از یک آرایه داخلی و HashSet با استفاده از HashMap داخلی پیاده سازی می شود .
-
یک ArrayList ترتیب درج عناصر را حفظ می کند، در حالی که HashSet یک مجموعه نامرتب است و ترتیب عناصر را حفظ نمی کند.
-
ArrayList اجازه می دهد تا هر تعداد از مقادیر خالی (null) را فراهم کند، فقط یک مقدار null را می توان در HashSet درج کرد (در نهایت، منحصر به فرد بودن عناصر).
91. چرا چنین تنوعی در پیاده سازی آرایه های پویا در جاوا وجود دارد؟
خب، این بیشتر یک سوال فلسفی است. خوب، چرا آنها با بسیاری از فن آوری های مختلف جدید می آیند؟ برای راحتی. در واقع، با تعداد زیادی از پیادهسازی آرایههای پویا یکسان است. هیچ کدام را نمی توان بهترین یا ایده آل نامید. هر کدام در یک موقعیت خاص یک مزیت دارند. و وظیفه ما این است که تفاوت ها، نقاط قوت / ضعف آنها را بشناسیم: تا بتوانیم از مناسب ترین آنها در موقعیت مناسب استفاده کنیم.92. چرا چنین تنوعی از پیاده سازی های ذخیره سازی کلید-مقدار در جاوا وجود دارد؟
در اینجا وضعیت مانند اجرای آرایه پویا است. بهترین کسی وجود ندارد: هر کدام نقاط قوت و ضعفی دارند. و البته ما باید از نقاط قوت خود نهایت استفاده را ببریم. مثال: بسته همزمان، که شامل بسیاری از فناوری های چند رشته ای است، مجموعه های همزمان خود را دارد . همان ConcurrentHashMap در ایمنی کار چند رشته ای با داده ها در مقایسه با HashMap معمولی مزیت دارد ، اما در یک محیط غیر چند رشته ای سرعت آن را از دست می دهد. خب، پیادهسازیهایی که در هیچ شرایطی قویترین نیستند، به تدریج استفاده از آنها متوقف میشود. مثال: Hashtable در ابتدا در نظر گرفته شده بود تا یک HashMap ایمن رشته ای باشد ، اما ConcurrentHashMap از آن در یک محیط چند رشته ای بهتر عمل کرد و Hashtable در نهایت فراموش شد و دیگر استفاده نشد.93. چگونه مجموعه ای از عناصر را مرتب کنیم؟
اولین چیزی که باید گفت این است که کلاس عنصر مجموعه باید رابط Comparable و متد compareTo آن را پیاده سازی کند . یا به کلاسی نیاز دارید که Comaprator را با متد مقایسه کننده خود پیاده سازی کند . در این پست می توانید اطلاعات بیشتری در مورد آنها بخوانید . هر دو روش مشخص می کنند که چگونه اشیاء از یک نوع معین باید مقایسه شوند. هنگام مرتبسازی، این امر بسیار مهم است، زیرا باید این اصل را درک کنید که با آن عناصر میتوانند مقایسه شوند. راه اصلی برای انجام این کار پیاده سازی Comparable است که مستقیماً در کلاسی که می خواهید مرتب کنید پیاده سازی شده است. در عین حال، استفاده از Comparator کمتر رایج است. فرض کنید از کلاسی از کتابخانه ای استفاده می کنید که پیاده سازی Comparable ندارد ، اما باید به نحوی آن را مرتب کنید. بدون اینکه بتوانید کد این کلاس را تغییر دهید (به جز با گسترش آن)، می توانید یک پیاده سازی از Comparator بنویسید که در آن مشخص کنید که بر اساس چه اصل می خواهید اشیاء این کلاس را با هم مقایسه کنید. و یک مثال دیگر. فرض کنید برای مرتبسازی اشیاء از یک نوع به اصول مختلفی نیاز دارید، بنابراین چندین مقایسه مینویسید که در موقعیتهای مختلف استفاده میکنید. به عنوان یک قاعده، بسیاری از کلاسهای خارج از جعبه قبلاً رابط Comparable را پیادهسازی میکنند - همان رشته . در واقع، هنگام استفاده از آنها، لازم نیست نگران نحوه مقایسه آنها باشید. شما فقط آنها را بگیرید و از آنها استفاده کنید. اولین و واضح ترین راه استفاده از مجموعه ای از نوع TreeSet یا TreeMap است که عناصر را به ترتیب مرتب شده با توجه به مقایسه کننده کلاس عنصر ذخیره می کند. به یاد داشته باشید که TreeMap کلیدها را مرتب می کند، اما مقادیر را نه. اگر از پیاده سازی Comparator به جای Comparable استفاده می کنید ، باید شی آن را به سازنده مجموعه ارسال کنید.TreeSet treeSet = new TreeSet(customComparator);
اما اگر نوع متفاوتی از مجموعه داشته باشید چه؟ چگونه آن را مرتب کنیم؟ در این مورد، روش دوم کلاس ابزار Collections مناسب است - متد sort() . استاتیک است، بنابراین تنها چیزی که نیاز دارید نام کلاس و روشی است که لیست مورد نیاز به آن ارسال می شود. مثلا:
Collections.sort(someList);
اگر از Comparable استفاده نمی کنید ، بلکه از اجرای Comparator استفاده می کنید، باید آن را به عنوان پارامتر دوم ارسال کنید:
Collections.sort(someList, customComparator);
در نتیجه، ترتیب داخلی عناصر لیست ارسال شده تغییر می کند: طبق مقایسه کننده عنصر مرتب می شود. توجه می کنم که لیست عناصر منتقل شده باید قابل تغییر باشد، یعنی. قابل تغییر است، در غیر این صورت روش کار نخواهد کرد و UnsupportedOperationException پرتاب می شود . به عنوان راه سوم ، میتوانید از عملیات مرتبسازی جریانی استفاده کنید که در صورت استفاده از اجرای Comparable، عناصر مجموعه را مرتب میکند :
someList = someList.stream().sorted().collect(Collectors.toList());
اگر مقایسه کننده :
someList = someList.stream().sorted(customComparator).collect(Collectors.toList());
در این مقاله می توانید اطلاعات بیشتری در مورد استریم بخوانید . روش چهارم اجرای دستی مرتبسازی است، مانند مرتبسازی حبابی یا مرتبسازی ادغام .
ClassObject. برابر و هش کد
94. توضیح مختصری از شی کلاس در جاوا ارائه دهید
در قسمت دوم تجزیه و تحلیل، قبلاً در مورد متدهای کلاس Object صحبت کردیم و یادآوری می کنم که کلاس Object مولد همه کلاس ها در جاوا است. دارای 11 متد است که بر این اساس به همه کلاس ها به ارث می رسد. اطلاعات مربوط به هر 11 روش را می توان در قسمت دوم بحث یافت .95. Equals و HashCode در جاوا چه کاربردی دارند؟
hashCode() متدی از کلاس Object است که توسط همه کلاس ها به ارث می رسد. وظیفه آن تولید تعدادی است که نشان دهنده یک شی خاص است. نمونه ای از استفاده از این روش، استفاده از آن در HashMap بر روی یک شی کلیدی برای تعیین بیشتر هش کد محلی است که سلول آرایه داخلی (سطل) را مشخص می کند که جفت در آن ذخیره می شود. ما در بخش 9 تجزیه و تحلیل به طور مفصل در مورد کار HashMap صحبت کردیم ، بنابراین زیاد روی این موضوع تمرکز نمی کنیم. همچنین قاعدتاً از این روش در متد () quals به عنوان یکی از ابزارهای اصلی آن برای تعیین هویت اشیا استفاده می شود. ()quals متدی از کلاس Object است که وظیفه آن مقایسه اشیاء و تعیین مساوی بودن یا نبودن آنهاست. این روش در همه جا که نیاز به مقایسه اشیاء داریم استفاده می شود، زیرا مقایسه معمول با استفاده از == برای اشیا مناسب نیست، زیرا فقط پیوندها را با آنها مقایسه می کند.96. در مورد قرارداد بین Equals و HashCode در جاوا بگویید؟
اولین چیزی که می گویم این است که برای اینکه متدهای ()quals() و hashCode() به درستی کار کنند ، باید به درستی override شوند. پس از این، آنها باید قوانین را دنبال کنند:- اشیاء یکسانی که مقایسه آنها از طریق برابر با مقدار true، باید دارای کدهای هش یکسان باشند.
- اشیا با کدهای هش یکسان ممکن است همیشه برابر نباشند.
GO TO FULL VERSION