89. ArrayList LinkedList-dən nə ilə fərqlənir?
Bu, HashMap-ın daxili strukturu ilə bağlı sualla yanaşı ən populyar suallardan biridir . Heç bir müsahibə onsuz tamamlanmır və buna görə də ona cavab "dişlərinizdən sıçrayacaq". Aşkar olanlara əlavə olaraq - müxtəlif adlar - daxili quruluşda fərqlənirlər. Əvvəllər biz həm ArrayList , həm də LinkedList- in daxili strukturunu araşdırdıq , ona görə də onların həyata keçirilməsinin təfərrüatlarına varmayacağam. Xatırlatmaq istərdim ki, ArrayList daxili massiv əsasında həyata keçirilir və düstura uyğun olaraq lazım olduqda artırılır:<размерТекущегоМассива> * 3 / 2 + 1
Eyni zamanda, LinkedList daxili ikiqat əlaqəli siyahı əsasında həyata keçirilir, yəni siyahının əvvəli/sonu olan dəyərlər istisna olmaqla, hər bir elementin əvvəlki və sonrakı ilə əlaqəsi var. İnsanlar sizi tutmaq ümidi ilə bu sualı "Hansı daha yaxşıdır - ArrayList və ya LinkedList ?" formatında verməyi sevirlər . Axı cavab olaraq onlardan birini göstərsəniz, səhv cavab olacaq. Bunun əvəzinə, hansı konkret vəziyyətdən danışdığınızı aydınlaşdırmalısınız - indeks girişi və ya siyahının ortasına daxil edilməsi. Cavabdan asılı olaraq seçiminizi izah edə biləcəksiniz. ArrayList və LinkedList-in bu və ya digər vəziyyətdə necə işlədiyini əvvəllər təsvir etmişdim . Müqayisə üçün onları eyni səhifəyə qoymaqla bunları ümumiləşdirək: Element əlavə etmək (əlavə etmək)
-
Добавление нового 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-dən nə ilə fərqlənir?
ArrayList və LinkedList-i əməliyyatlar baxımından müqayisə etmək olarsa - bu daha yaxşıdır - ArrayList -i HashSet ilə müqayisə etmək o qədər də asan deyil , çünki bunlar tamamilə fərqli kolleksiyalardır. Bir şirin yeməyi digəri ilə müqayisə edə bilərsiniz, ancaq ət yeməyi ilə işləyəcək - onlar çox fərqlidir. Bununla belə, onlar arasında bəzi fərqlər verməyə çalışacağam:-
ArrayList List interfeysini , HashSet isə Set interfeysini həyata keçirir ;
-
ArrayList -də giriş element indeksi ilə mümkündür: get əməliyyatı O(1) alqoritmik mürəkkəbliyə malikdir və HashSet- də tələb olunan element yalnız kobud qüvvə ilə əldə edilə bilər və bu O(1) -dən O(n) -a qədərdir. ;
-
ArrayList dublikat elementlərə imkan verir. HashSet -də bütün elementlər unikaldır: analoqu kolleksiyada artıq mövcud olan HashSet- ə element əlavə etmək işləməyəcək (dublikatlar hashcode istifadə edərək yoxlanılır, buna görə də bu kolleksiyanın adı);
-
ArrayList daxili massivdən istifadə etməklə həyata keçirilir və HashSet daxili HashMap istifadə edərək həyata keçirilir ;
-
ArrayList elementlərin daxil edilmə qaydasını saxlayır, HashSet isə sıralanmamış çoxluqdur və elementlərin sırasını saxlamır;
-
ArrayList istənilən sayda boş dəyərə imkan verir (null), HashSet- ə yalnız bir null dəyər daxil edilə bilər (hər şeydən sonra elementlərin unikallığı).
91. Nəyə görə Java-da bu qədər müxtəlif dinamik massiv tətbiqləri mövcuddur?
Yaxşı, bu daha çox fəlsəfi sualdır. Yaxşı, niyə bu qədər fərqli yeni texnologiyalar ortaya qoyurlar? Rahatlıq üçün. Əslində, çoxlu sayda dinamik massiv tətbiqləri ilə eynidir. Onların heç birini ən yaxşı və ya ideal adlandırmaq olmaz. Hər birinin müəyyən bir vəziyyətdə üstünlüyü var. Və bizim vəzifəmiz onların fərqlərini, güclü/zəif tərəflərini bilməkdir: düzgün vəziyyətdə ən uyğununu istifadə edə bilmək üçün.92. Java-da niyə bu qədər müxtəlif açar-dəyər saxlama tətbiqləri mövcuddur?
Burada vəziyyət dinamik massiv tətbiqləri ilə eynidir. Ən yaxşısı yoxdur: hər birinin güclü və zəif tərəfləri var. Və biz, əlbəttə ki, güclü tərəflərimizdən maksimum istifadə etməliyik. Nümunə: bir çox çox yivli texnologiyaları ehtiva edən paralel paketin öz Concurrent kolleksiyaları var. Eyni ConcurrentHashMap adi HashMap ilə müqayisədə verilənlərlə çox yivli işin təhlükəsizliyində üstünlüyə malikdir , lakin çox yivli olmayan mühitdə sürəti itirir. Yaxşı, heç bir vəziyyətdə ən güclü olmayan tətbiqlər tədricən istifadəni dayandırır. Nümunə: Hashtable əvvəlcə mövzu üçün təhlükəsiz HashMap olmaq üçün nəzərdə tutulmuşdu , lakin ConcurrentHashMap çox yivli mühitdə onu üstələyib və Hashtable nəhayət unudulub və artıq istifadə olunmayıb.93. Elementlər toplusunu necə çeşidləmək olar?
Demək lazım olan ilk şey odur ki, kolleksiya element sinfi Comparable interfeysini və onun compareTo metodunu tətbiq etməlidir . Və ya sizə Comparator metodu ilə Comaprator tətbiq edən sinif lazımdır . Bu yazıda onlar haqqında daha çox oxuya bilərsiniz . Hər iki üsul müəyyən tipli obyektlərin necə müqayisə olunacağını müəyyənləşdirir. Çeşidləmə zamanı bu çox vacibdir, çünki elementlərin müqayisə oluna biləcəyi prinsipi başa düşməlisiniz. Bunun əsas yolu , birbaşa çeşidləmək istədiyiniz sinifdə həyata keçirilən Comparable tətbiqidir . Eyni zamanda, Comparator- dan istifadə daha az yaygındır. Tutaq ki, siz müqayisə edilə bilən tətbiqi olmayan bəzi kitabxananın sinifindən istifadə edirsiniz , lakin siz onu hansısa şəkildə çeşidləməlisiniz. Bu sinfin kodunu dəyişdirə bilmədən (onu genişləndirmək istisna olmaqla), siz bu sinfin obyektlərini hansı prinsiplə müqayisə etmək istədiyinizi bildirdiyiniz Comparator tətbiqini yaza bilərsiniz. Və daha bir misal. Tutaq ki, eyni tipli obyektlərin çeşidlənməsi üçün sizə müxtəlif prinsiplər lazımdır, ona görə də müxtəlif situasiyalarda istifadə etdiyiniz bir neçə Müqayisəçi yazırsınız. Bir qayda olaraq, qutudan kənar bir çox sinif artıq Müqayisəli interfeysi - eyni String tətbiq edir . Əslində, onlardan istifadə edərkən, onları necə müqayisə edəcəyiniz barədə narahat olmaq lazım deyil. Siz sadəcə onları götürün və istifadə edin. Birinci və ən açıq yol , element sinfi müqayisəçisinə uyğun olaraq elementləri artıq çeşidlənmiş qaydada saxlayan TreeSet və ya TreeMap tipli kolleksiyadan istifadə etməkdir . Unutmayın ki, TreeMap açarları çeşidləyir, lakin dəyərləri deyil. Comparable yerinə Comparator tətbiqindən istifadə etsəniz , yaradıldıqdan sonra onun obyektini kolleksiya konstruktoruna ötürməli olacaqsınız:TreeSet treeSet = new TreeSet(customComparator);
Bəs fərqli bir kolleksiyanız varsa nə olacaq? Necə çeşidləmək olar? Bu halda Collections utility sinfinin ikinci metodu uyğun gəlir - sort() metodu . O, statikdir, ona görə də sizə lazım olan tək şey sinfin adı və tələb olunan siyahının ötürüldüyü metoddur. Misal üçün:
Collections.sort(someList);
Əgər siz Comparable istifadə etmirsinizsə , əksinə Comparator tətbiqini istifadə edirsinizsə , onu ikinci parametr kimi keçirməlisiniz:
Collections.sort(someList, customComparator);
Nəticədə, keçmiş siyahının elementlərinin daxili sırası dəyişəcək: element müqayisəçisinə uyğun olaraq sıralanacaq. Qeyd edim ki, ötürülən elementlərin siyahısı dəyişkən olmalıdır, yəni. dəyişdirilə bilər, əks halda metod işləməyəcək və UnsupportedOperationException atılacaq . Üçüncü üsul olaraq , müqayisə edilə bilən tətbiq istifadə edilərsə, kolleksiyanın elementlərini çeşidləyən Stream sort əməliyyatından istifadə edə bilərsiniz :
someList = someList.stream().sorted().collect(Collectors.toList());
Əgər müqayisəçi :
someList = someList.stream().sorted(customComparator).collect(Collectors.toList());
Bu məqalədə Stream haqqında ətraflı oxuya bilərsiniz . Dördüncü üsul, qabarcıq çeşidləmə və ya birləşmə sort kimi çeşidləməni əl ilə həyata keçirməkdir .
ClassObject. Bərabər və HashCode
94. Java-da sinif obyektinin qısa təsvirini verin
Təhlilin ikinci hissəsində biz artıq Object sinifinin metodları haqqında danışdıq və sizə xatırladacağam ki, Obyekt sinfi Java-da bütün siniflərin sələfidir. Onun 11 metodu var ki, bu da müvafiq olaraq bütün siniflər tərəfindən miras alınır. Bütün 11 üsul haqqında məlumatı müzakirənin ikinci hissəsində tapa bilərsiniz .95. Java-da Equals və HashCode nə üçün istifadə olunur?
hashCode() bütün siniflər tərəfindən miras qalan Obyekt sinifinin metodudur . Onun vəzifəsi müəyyən bir obyekti təmsil edən bəzi nömrələr yaratmaqdır. Bu metoddan istifadə nümunəsi , cütün saxlanacağı daxili massivin (kovanın) xanasını təyin edəcək yerli hashkodu daha da müəyyən etmək üçün onun əsas obyektdə HashMap- da istifadəsidir . Biz təhlilin 9-cu hissəsində HashMap- ın işi haqqında ətraflı danışdıq , ona görə də bu barədə çox dayanmayacağıq. Həmçinin, bir qayda olaraq, bu üsul obyektlərin eyniliyini təyin etmək üçün onun əsas vasitələrindən biri kimi equals() metodunda istifadə olunur. equals() işi obyektləri müqayisə etmək və onların bərabər olub-olmadığını müəyyən etmək olan Object sinifinin metodudur . Bu üsul obyektləri müqayisə etmək lazım olan hər yerdə istifadə olunur, çünki == istifadə edərək adi müqayisə obyektlər üçün uyğun deyil, çünki yalnız onlara olan keçidləri müqayisə edir.96. Java-da Equals və HashCode arasındakı müqavilə haqqında bizə məlumat verin?
İlk deyəcəyim odur ki, equals() və hashCode() metodlarının düzgün işləməsi üçün onların düzgün şəkildə ləğv edilməsi lazımdır. Bundan sonra onlar qaydalara əməl etməlidirlər:- Bərabər vasitəsilə müqayisənin doğru qaytardığı eyni obyektlərin eyni hash kodları olmalıdır ;
- eyni hash kodları olan obyektlər həmişə bərabər olmaya bilər.
GO TO FULL VERSION