Сәлеметсіз бе! Бүгінгі дәріс
ArrayList
алдыңғыларға қарағанда бір жағынан қарапайым, екінші жағынан қиынырақ болмақ. Бұл қиынырақ, өйткені бүгін біз «қапшық астында» қарап ArrayList
, операция кезінде не болатынын зерттейміз. Екінші жағынан, бұл лекцияда code дерлік болмайды - негізінен суреттер мен түсіндірмелер. Сонымен, кеттік :) Өздеріңіз білетіндей, ArrayList
«a» ішінде деректер қоймасы ретінде әрекет ететін қарапайым массив бар. Көп жағдайда біз тізімнің нақты өлшемін көрсетпейміз. Бірақ ішкі массивтің өлшемі болуы керек! Дәл солай. Оның әдепкі өлшемі [10] болып табылады .
public static void main(String[] args) {
ArrayList<Car> cars = new ArrayList<>();
}
Алдымен, жаңа элемент қосудың қалай болатынын қарастырайық. Ең алдымен, ішкі массивте жеткілікті орын бар-жоғын және тағы бір элемент сәйкес келетінін тексеру үшін тексеріледі . Егер бос орын болса, жаңа элемент тізімнің соңына қосылады. «Соңына дейін» дегенде біз массивтің соңғы ұяшығын білдірмейміз (бұл біртүрлі болар еді). Бұл соңғы ағымдағы элементтің жанындағы ұяшыққа қатысты. Оның индексі -ге тең болады cars.size()
. Біздің тізім қазір бос ( cars.size() = 0
). Сәйкесінше, индексі бар ұяшыққа жаңа элемент қосылады 0
.
ArrayList<Car> cars = new ArrayList<>();
Car ferrari = new Car("Ferrari 360 Spider");
cars.add(ferrari);
Мұнда бәрі түсінікті. Кірістіру ортасында, яғни бірнеше элементтер арасында жүргізілсе не болады?
public static void main(String[] args) {
ArrayList<Car> cars = new ArrayList<>();
Car ferrari = new Car("Ferrari 360 Spider");
Car bugatti = new Car("Bugatti Veyron");
Car lambo = new Car("Lamborghini Diablo");
Car ford = new Car("Ford Modneo");
cars.add(ferrari);
cars.add(bugatti);
cars.add(lambo);
cars.add(1, ford);//добавляем ford в ячейку 1, которая уже занята
}
Тағы да, ол алдымен массивте жеткілікті орын бар-жоғын тексереді. Егер бос орын жеткілікті болса, элементтер жаңа элементті енгізетін ұяшықтан бастап оңға жылжытылады . Біз индексі 1 ұяшыққа қоямыз. Яғни 3-ұяшықтағы элемент 4-ұяшыққа, 2-элемент 3-ұяшыққа, 1-элемент 2-ұяшыққа көшіріледі. Осыдан кейін біздің жаңа элементіміз орнына қойылады. Алдыңғы элемент ( bugatti
) сол жерден жаңа орынға көшірілген. Енді массивте кірістіру үшін бос орын болмаса, бұл процесс қалай болатынын анықтайық. Алдымен, әрине, жеткілікті орын бар-жоғын тексеру жүргізіледі. Егер орын жеткіліксіз екені анықталса, ArrayList
'a ішінде жаңа өлшемді массив (OldArray өлшемі * 1,5) + 1 жасалады.Біздің жағдайда жаңа массивтің өлшемі 16 ұяшық болады. Барлық ағымдағы элементтер сол жерге дереу көшіріледі. Ескі массив қоқыс жинағыш арқылы жойылады және тек жаңа, кеңейтілген массив қалады. Енді жаңа элемент үшін бос орын бар. Біз оны алып жатқан 3 ұяшыққа қоямыз. Енді таныс proceduresа басталады. 3 индексінен басталатын барлық элементтер бір ұяшықты оңға жылжытады және жаңа элемент тыныш қосылады. Енді кірістіру сәтті аяқталды! Біз кірістіруді сұрыптадық. Енді элементтерді жою туралы сөйлесейік . Естеріңізде болса, массивтермен жұмыс істеу кезінде біз мәселеге тап болдық: біз оларды жойған кезде, онда «тесік» қалды. Жалғыз шешім элементтерді жойылған сайын солға жылжыту болды және сіз ауысымның codeын өзіңіз жазуыңыз керек еді. ArrayList
сол принцип бойынша жұмыс істейді, бірақ онда бұл механизм қазірдің өзінде автоматты түрде жүзеге асырылады. Бұл келесідей: және соңында біз қажетті нәтиже аламыз: элемент lambo
сәтті жойылды. Міне, біз ортадан алып тастауды жасадық. Тізімнің соңынан жою жылдамырақ болатыны анық, өйткені қалаған элемент қалғандарының барлығын ауыстырмай жойылады. Ішкі массивтің өлшемін және оның жадта сақталуын тағы бір қарастырайық. Массивтің кеңеюі – белгілі бір ресурстар көлемін алатын процесс. ArrayList
Сондықтан, оның кемінде 100 элементі болатынына сенімді болсаңыз, әдепкі өлшеммен жасамауыңыз керек . 100-ші элементті кірістіруге жеткенде, ішкі массив барлық элементтерді тасымалдаған сайын 6 есе кеңейеді.
- 10 элементтен 16 элементке дейін
- 16 элементтен 25-ке дейін
- 25-тен 38-ге дейін
- 38-ден 58-ге дейін
- 58-ден 88-ге дейін
- 88-ден 133-ке дейін (формула бойынша (ескі массивтің өлшемі * 1,5) + 1)
ArrayList<Car> cars = new ArrayList<>(100);
Енді 100 элементтен тұратын массив жадта бірден бөлінеді, бұл тиімдірек болады, себебі ресурстар кеңейтуге жұмсалмайды. Монетаның екінші жағы да бар. Нысандар ішкі массивтен жойылған кезде ArrayList
өлшем автоматты түрде кішіреймейді. Мысалы, бізде ArrayList
толығымен толтырылған 88 элементтен тұратын ішкі массив бар: Бағдарлама жұмысы кезінде біз одан 77 элементті алып тастаймыз және онда тек 11 элемент қалады: Сіз мәселенің не екенін білдіңіз бе? Жадты тиімсіз пайдалану, әрине! Біз тек 11 ұяшықты пайдаланамыз, ал бізде 88 элементке арналған жады бар - бұл бізге қажеттен 8 есе көп! Бұл жағдайда оңтайландыруды жүзеге асыру үшін арнайы класс әдісін қолдануға болады ArrayList
- trimToSize()
. Ол ішкі массивтің ұзындығын онда сақталған элементтер санына дейін «қиғарады». Енді қажет болғанша жад бөлінеді! :)
GO TO FULL VERSION