JavaRush /Java блогы /Random-KK /Java тіліндегі динамикалық массивтер

Java тіліндегі динамикалық массивтер

Топта жарияланған
Күрделілігі әртүрлі бағдарламаларды жасау кезінде әрбір әзірлеуші ​​массивтерді қоса алғанда көптеген деректер түрлерін пайдаланады. Бұл құрылым бір түрдегі жиынтықты сақтауға өте қолайлы, тамаша өнімділікті қамтамасыз етеді және жалпы ыңғайлы. Java тіліндегі динамикалық массивтер - 1Массивтердің елеулі кемшілігі олардың статикалық болуы: олардың өлшемін алдын ала көрсету керек. Дегенмен, бағдарламашылар болашақты қалай болжауға болатынын әлі білмейді (егер, әрине, ақпаратты керемет жылдам өңдейтін және кез келген оқиғаларды болжай алатын AI пайда болмаса). Осы себепті біз бағдарлама жұмыс істеп тұрған кезде оның өлшемін өзгерте алатын құрылымды жасадық. Ол динамикалық массив деп аталады .

JavaRush курсындағы динамикалық массивтер

Бұл тақырып Java Syntax квестіндегі JavaRush курсының 7 деңгейінде және ішінара 8 деңгейінде өте түсінікті және анық қамтылған . Бірнеше дәріс және 18 есеп барысында негізгі мәселелер, динамикалық массивтердің түрлері және олардың арасындағы айырмашылық, соның ішінде өнімділік қарастырылады. Бұл тақырып өте маңызды, өйткені динамикалық массивтер әзірлеушіні депрессиядан, бас ауруынан босатады және керемет уақытты үнемдейді.

Динамикалық массив дегеніміз не?

Динамикалық массив – программаның орындалу барысында өлшемін өзгерте алатын массив. Java тілінде бұл рөлді негізінен ArrayList және LinkedList кластары атқарады. Массивтерден айырмашылығы, ArrayList және LinkedList тек анықтамалық деректер түрлерін қамтиды, яғни олар тек нысандарды сақтай алады. Бақытымызға орай, Java-да динамикалық массивтерде қарабайыр типтерді сақтауға мүмкіндік беретін автобокс және автобокс механизмдері бар. Статикалық массив сияқты динамикалық массив біртекті болып табылады, яғни ол бір деректер түрін сақтай алады. Дегенмен, мұрагерлік механизмнің және интерфейстерді дұрыс пайдаланудың арқасында бір динамикалық массивте бір жалпыдан мұраланған әртүрлі класстардың тұтас ауқымын сақтауға болады, бірақ төменде бұл туралы көбірек. Яғни, статикалық массив келесідей жұмыс істейді: Java тіліндегі динамикалық массивтер - 2Ал Java-дағы динамикалық массив келесідей жұмыс істейді (үшінші қадамдағы диаграмманы жалғастыру): Java тіліндегі динамикалық массивтер – 3Java массивді көшіру үшін арнайы жергілікті функцияны пайдаланады, сондықтан мұндай «жылжыту» онша емес. қымбат.

Неліктен бізге динамикалық массив қажет?

Java тіліндегі динамикалық массив бағдарлама жазылған кезде өлшемі белгісіз біртекті деректер жиынын өңдеу үшін қолданылады. Мысалы, қазіргі уақытта қолданбаны пайдаланып жатқан әрбір клиенттің деректерін кэштеу қажет болуы мүмкін. Мұндай клиенттердің санын алдын ала болжау мүмкін емес. Динамикалық массивтерсіз бұл мәселені келесі опциялармен шешуге болады:
  1. Қажеттілікті 100% өтейтін үлкен массив жасаңыз;
  2. Буфер ретінде әрекет ететін статикалық массив жасаңыз;
  3. Жиындар сияқты басқа динамикалық құрылымдарды қолданыңыз.
Бірінші нұсқа қатаң шектеулі диапазон жағдайында ғана жарамды. Басқа жағдайларда мұндай массив жадтың үлкен көлемін алады, бұл өте тиімсіз. Екіншісі буферді тазарту, оқу және т.б. үшін қосымша механиканы енгізуді талап етеді. Үшіншісі де функционалдық айырмашылықтарға байланысты кемшіліктерге ие.

Java тіліндегі динамикалық массив қандай қызмет атқарады

Java тілінде ArrayList және LinkedList кластары динамикалық массив ретінде әрекет етеді. Ең жиі қолданылатыны ArrayList болып табылады, өйткені ол қос байланысқан тізім тұжырымдамасын жүзеге асыратын LinkedList-ке қарағанда классикалық массив ретінде әрекет етеді. Бұл туралы сәл кейінірек айтатын боламыз.

ArrayList, LinkedList – түсініктер және жұмыс ережелері

ArrayList - бұл бағдарламаны орындау кезінде кеңейтуге болатын классикалық массив. Ол кәдімгі массивке негізделген: жасалған кезде оның өлшемі 10 элементті құрайды. Көлемі ұлғайған сайын сыйымдылық артады. ArrayList жұмыс істейтін ережелер:
  • Статикалық массив сияқты ол 0-ден индекстеледі;
  • Соңында кірістіру және индекс бойынша қол жеткізу өте жылдам - ​​O(1);
  • Элементті басына немесе ортасына кірістіру үшін барлық элементтерді бір ұяшыққа оңға көшіру керек, содан кейін қажетті орынға жаңа элементті қою керек;
  • Мән бойынша қол жеткізу элементтер санына байланысты – O(n);
  • Классикалық массивтен айырмашылығы, ол нөлді сақтай алады;
LinkedList жағдайында бәрі біршама күрделірек: ол қосарланған тізімге негізделген. Яғни, құрылымдық жағынан бұл динамикалық Java массиві бір-біріне сілтеме жасайтын шашыраңқы нысандардың саны болып табылады. Суреттермен түсіндіру оңайырақ. HeadLinkedList ішінде бізде элементтер саны туралы ақпаратты, сондай-ақ бірінші және соңғы элементтерге сілтемені сақтайтын негізгі нысан бар : Java тіліндегі динамикалық массивтер – 4Енді өріс size = 0, firstжәне last = null. Осы тізімге қосылған әрбір элемент жеке ішкі нысанның мазмұны болып табылады. Элементті қосамыз Johnny: Java тіліндегі динамикалық массивтер – 5Енді бізде «Джонни» мәні бар түйін бар. Негізгі элемент үшін бірінші және соңғы элементке сілтемелер жаңа түйінді көрсетеді. Бұл нысанның алдыңғы және келесі элементтерге сілтемелері де бар. Алдыңғыға сілтеме әрқашан нөл болады, өйткені бұл бірінші элемент, ал келесіге сілтеме әрқашан нөл болады, себебі ол әлі жоқ. Мұны түзетейік: Java тіліндегі динамикалық массивтер – 6«Уотсон» мәні бар жаңа элемент қосылды, ол екінші болды. Бірінші элементте nextкелесі элементке нұсқайтын өріс бар, ал жаңа элементте previousалдыңғыға нұсқайтын өріс бар екенін ескеріңіз. Негізгі элемент үшін соңғы элементке сілтеме енді жаңа түйінді көрсетеді. Келесі диаграмма тізімнің ортасына элементтерді қосу жолын көрсетеді: Java тіліндегі динамикалық массивтер – 7«Хамиш» жаңа элементі қосылды. Оны тізімнің ортасына енгізу үшін суретте көрсетілгендей элементтерге сілтемелерді қайта тағайындау жеткілікті. Бұл иллюстрациялар егжей-тегжейге тоқталмай-ақ, жоғарғы деңгейде қосарланған тізімнің процесін түсіндіреді. LinkedList туралы оқиғаны қорытындылау үшін оның жұмыс істеуінің бірнеше ережелерін алуға болады:
  • Массив сияқты ол 0-ден бастап индекстеледі;
  • Бірінші және соңғы элементке қол жеткізу элементтер санына байланысты емес - O(1);
  • Элементті индекс бойынша алу, тізімнің ортасынан кірістіру немесе жою элементтер санына байланысты - O(n);
  • Итератор механизмін пайдалануға болады: содан кейін кірістіру және жою тұрақты уақытта орын алады;
  • Классикалық массивтен айырмашылығы, ол нөлді сақтай алады.

Код мысалдары

Кейбір мысалдарды қарастырайық. Код үзінділері ArrayList және LinkedList үшін мысалдарды қамтиды.

Жасау

// Создаем новый список
ArrayList<String> arrayList = new ArrayList<>();
// Создается новый список и указывается начальный размер внутреннего массива
ArrayList<String> arrayListLarge = new ArrayList<>(100000);

// Создаем новый LinkedList
LinkedList<String> linkedList = new LinkedList<>();

Элемент қосу

// Новый элемент добавляется в конец
arrayList.add("Johhny");
// Новый элемент добавляется в указанную позицию (в данном случае — в начало)
arrayList.add(0, "Watson");

// Новый элемент добавляется в конец двусвязного списка
linkedList.add("Java");
// Новый элемент добавляется в нулевую позицию списка:
linkedList.addFirst("I think");
// Новый элемент добавляется в конец списка
linkedList.addLast("language");
// Новый элемент добавляется в указанную позицию
linkedList.add(2, "is a terrific");

// Получение размера списков
int arraySize = arrayList.size(); // 2
int linkedSize = linkedList.size(); // 4
Бір қарағанда, add()ЖӘНЕ әдістері addLast()бірдей функционалдылықты орындайды, бірақ әдіс add()LinkedList-ке интерфейстен келді List, ал әдіс addLastинтерфейстен келді Deque. LinkedList осы интерфейстердің екеуін де жүзеге асырады. Бұл жағдайда контекстке ең қолайлы әдісті қолдану жақсы тәжірибе болар еді. Егер LinkedList кезек ретінде пайдаланылса, онда addLast. Егер LinkedList тізім ретінде пайдаланылса, пайдалану орынды болар еді add().

Элементті жою

// Удаление element по индексу
arrayList.remove(0);
// Удаление element по значению
arrayList.remove("Johnny");

// Удаление первого element в списке
linkedList.removeFirst();
// Удаление первого element в списке, фактически вызов предыдущего метода
linkedList.remove();
// Удаление последнего element в списке
linkedList.removeLast();
// Удаление первого вхождения element в список
linkedList.removeFirstOccurrence("language");
// Удаление последнего вхождения element в список
linkedList.removeLastOccurrence("Java");
// Удаление по индексу
linkedList.remove(2);
Егер нысан индекс бойынша жойылса, әдіс жойылған нысанды қайтарады. Егер нысан мән бойынша жойылса (немесе LinkedList-тің бірінші немесе соңғы элементтері жойылса), әдіс нысан табылған және жойылған жағдайда true мәнін қайтарады, әйтпесе жалған .

Элементке қол жеткізу және тізімді іздеу

// Доступ к элементу по индексу
String arrayElement = arrayList.get(2);
// Поиск element по значению
int arrayIndex = arrayList.indexOf("Watson");
// Поиск последнего индекса вхождения element в список
int lastArrayIndex = arrayList.lastIndexOf("Watson");

// Доступ по индексу
String linkedElement = linkedList.get(3);
// Получение первого element
String firstLinkedElement = linkedList.getFirst();
// Получение последнего element
String lastLinkedElement = linkedList.getLast();

// Поиск element по значению
int linkedIndex = linkedList.indexOf("Java");
// Поиск последнего индекса вхождения element в список
int lastLinkedIndex = linkedList.lastIndexOf("Java");

Ілмекпен жүру

// Использование обычного цикла
for(int i = 0; i<arrayList.size(); i++) {
  String value = arrayList.get(i);
  System.out.println(value);
}

for(int i = 0; i<linkedList.size(); i++) {
  String value = linkedList.get(i);
  System.out.println(value);
}

// Использование цикла for-each
for(String s : arrayList) {
  System.out.println(s);
}

for(String s : linkedList) {
  System.out.println(s);
}
Мұнда іздеу туралы бірнеше сөз айтқан жөн. indexOf()Көптеген бастаушы әзірлеушілер тізімдегі элементті іздегенде, әдістер мен әдістердің болуына қарамастан, барлық элементтерді ізделгенмен салыстыра отырып, іздеуді циклде бастайды lastIndexOf(). contains()Сондай-ақ , тізімде элемент бар екенін білу үшін әдісті пайдалануға болады :
boolean isContainsSherlock = arrayList.contains("Sherlock");
boolean isContainsPhp = linkedList.contains("Php");

Қосымша оқуға арналған сілтемелер

  1. Мұнда ArrayList тізімінен элементтерді жою туралы тамаша мақала бар . Бұл динамикалық Java массиві болғандықтан , элементтерді жоюда көптеген нәзіктіктер бар.
  2. ArrayList жұмысы осы жерде егжей-тегжейлі көрсетілген .
  3. LinkedList туралы аздап .
  4. ArrayList және LinkedList туралы Хабрдан бірнеше мақалалар .
Пікірлер
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION