JavaRush /Java блогу /Random-KY /Javaдагы динамикалык массивдер

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

Группада жарыяланган
Ар кандай деңгээлдеги татаалдыктагы программаларды түзүүдө ар бир иштеп чыгуучу көптөгөн маалыматтардын түрлөрүн, анын ичинде массивдерди колдонот. Бул структура бир типтеги топтомду сактоо үчүн абдан ылайыктуу, мыкты аткарууну камсыз кылат жана жалпысынан ыңгайлуу. Javaдагы динамикалык массивдер - 1Массивдердин олуттуу кемчorги алардын статикалык болушунда: алардын өлчөмү алдын ала көрсөтүлүшү керек. Бирок, программисттер келечекти алдын ала кантип болорун бorшпейт (албетте, информацияны укмуштуудай тез иштете турган жана ар кандай окуяларды алдын ала айта ала турган AI пайда болбосо). Ушул себептен улам, биз программа иштеп жатканда анын өлчөмүн өзгөртө ала турган структураны түздүк. Ал динамикалык массив деп аталат .

JavaRush курсундагы динамикалык массивдер

Бул тема Java Syntax квестинде JavaRush курсунун 7-деңгээлинде жана жарым-жартылай 8-деңгээлинде абдан түшүнүктүү жана так чагылдырылган . Бир нече лекциялардын жана 18ге жакын маселелердин жүрүшүндө негизги маселелер, динамикалык массивдердин түрлөрү жана алардын ортосундагы айырмачылык, анын ичинде аткаруучулук камтылган. Бул тема өтө маанилүү, анткени динамикалык массивдер иштеп чыгуучуну депрессиядан, баш оорудан арылтат жана укмуштуудай убакытты үнөмдөйт.

Динамикалык массив деген эмне?

Динамикалык массив – бул программанын аткарылышы учурунда өзүнүн өлчөмүн өзгөртө алган массив. Javaда бул ролду негизинен ArrayList жана LinkedList класстары ойнойт. Массивдерден айырмаланып, ArrayList жана LinkedList шилтеме маалымат түрлөрүн гана камтыйт, башкача айтканда, алар an objectтерди гана сактай алышат. Бактыга жараша, Java динамикалык массивдерде примитивдүү типтерди сактоого мүмкүндүк берген автобокс жана автобокс механизмдери бар. Статикалык массив сыяктуу эле, динамикалык массив да бир тектүү, башкача айтканда, бир типтеги маалыматтарды сактай алат. Бирок, мурастоо механизминин жана интерфейстерди туура колдонуунун аркасында бир динамикалык массивде бир жалпысынан тукум кууган ар кандай класстардын бүтүндөй диапазонун сактоого болот, бирок төмөндө бул боюнча көбүрөөк. Башкача айтканда, статикалык массив мындай иштейт: Javaдагы динамикалык массивдер - 2Жана Javaдагы динамикалык массив төмөнкүдөй иштейт (үчүнчү кадамдагы диаграмманы улантуу): Javaдагы динамикалык массивдер - 3Java массивди көчүрүү үчүн атайын жергorктүү функцияны колдонот, андыктан мындай "жылуу" анчалык деле эмес. кымбат.

Эмне үчүн бизге динамикалык массив керек?

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

Java'да динамикалык массив эмне кылат?

Java тorнде ArrayList жана LinkedList класстары динамикалык массивдин ролун аткарышат. Эң көп колдонулганы ArrayList, анткени ал классикалык массивдин ролун аткарат, ал LinkedList-тен айырмаланып, кош байланышкан тизменин концепциясын ишке ашырат. Бул тууралуу бир аздан кийин сүйлөшөбүз.

ArrayList, LinkedList - түшүнүктөр жана иштөө эрежелери

ArrayList - бул программаны аткаруу учурунда кеңейтorши мүмкүн болгон классикалык массив. Ал кадимки массивге негизделген: түзүлгөндө анын өлчөмү 10 элементти түзөт. Өлчөмү чоңойгон сайын кубаттуулугу да көбөйөт. ArrayList иштеген эрежелер:
  • Статикалык массив сыяктуу эле, ал 0ден индекстелет;
  • Аягына киргизүү жана индекс боюнча жетүү абдан тез - O(1);
  • Элементти башына же ортосуна кыстаруу үчүн, бардык элементтерди бир уячаны оңго көчүрүп, андан соң жаңы элементти керектүү жерге чапташыңыз керек болот;
  • Маани боюнча жетүү элементтердин санына жараша болот - O(n);
  • Классикалык массивден айырмаланып, ал нөлдү сактай алат;
LinkedList учурда баары бир аз татаалыраак: ал эки эселенген тизмеге негизделген. Башкача айтканда, структуралык жактан алганда, бул динамикалык Java массиви бири-бирине шилтеме кылган чачыранды an objectтердин саны. Сүрөттөр менен түшүндүрүү оңой. LinkedList ичинде бизде негизги an object бар Head, анда элементтердин саны жөнүндө маалымат сакталат, ошондой эле биринчи жана акыркы элементтерге шилтеме: Javaдагы динамикалык массивдер - 4Азыр талаа size = 0, firstжана last = null. Бул тизмеге кошулган ар бир элемент өзүнчө ички an objectтин мазмуну болуп саналат. Келгиле, элементти кошолу Johnny: Javaдагы динамикалык массивдер - 5Эми бизде "Джонни" мааниси бар түйүн бар. Негизги элемент үчүн биринчи жана акыркы элементке шилтемелер жаңы түйүндү көрсөтөт. Бул an objectтин мурунку жана кийинки элементтерге шилтемелери да бар. Мурункуга шилтеме дайыма нөл болот, анткени бул биринчи элемент, ал эми кийинкиге шилтеме дайыма нөл болот, анткени ал азырынча жок. Муну оңдойлу: 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);
Эгерде an object индекс боюнча жок кылынса, метод жок кылынган an objectти кайтарат. Эгерде an object маани боюнча жок кылынса (же LinkedListтин биринчи же акыркы элементтери жок кылынса), метод an object табылып, жок кылынса, чындыкты кайтарат, башка учурда жалган .

Бир нерсеге жетүү жана тизмеден издөө

// Доступ к элементу по индексу
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