1. Как ArrayListе структуриран

ArrayListе Java класът, използван най-често за съхраняване на елементи. И така, How ArrayListработи и защо всички го харесват толкова много?

Структурата на ArrayListе проста и гениална. Всеки ArrayListобект съдържа две полета:

  • Масив от елементи
  • Променлива size, която съхранява броя на елементите в списъка

Вътрешно ArrayListобектът съдържа най-обикновен масив! Но това не е всичко. Има и променлива размер , която съхранява дължината на списъка. Ето How работи:

Първоначално дължината на масива в списъка е 10. А променливата sizeе 0.

Ако добавите елемент към списъка, той ще бъде съхранен в 0-та клетка на масива и sizeще се увеличи до 1.

Ако добавите още един елемент, той ще се запише в 1-ва клетка и sizeотново ще се увеличи с 1 и ще стане equals на две.

Ако добавите друг елемент, когато няма повече място в масива, тогава в add()метода се случва следното:

  1. Създава се нов масив , който е един и половина пъти по-дълъг от предишния
  2. Всички елементи от стария масив се копират в новия масив.
  3. В ArrayListобекта препратката към новия масив замества препратката към стария .
  4. Предаденият елемент се записва в 10-та клетка на новия масив.
  5. Променливата за размера се увеличава с 1 и сега ще бъде равна на 11

Нещо подобно се случва при добавяне (вмъкване) на елемент в средата на списъка. Съществуващите елементи се изместват с 1 надясно, а преминалият елемент се записва в новоосвободената клетка на масива.

Сега ще разгледаме най-основните сценарии, включващи списъци:


2. Добавяне на елемент къмArrayList

Нека да разгледаме Howво се случва в списъка, когато към него се добавят елементи. Веднага след създаването на обект ArrayList имаме нещо подобно в паметта:

Добавяне на елемент към ArrayList

Имаме ArrayListобект, който съдържа две полета (две променливи): контейнер (масив data) и брой съхранени елементи ( size). Променливата dataсъхранява препратка към контейнер (масив), който може да съхранява 10 елемента.

Ако решим да добавим числото 5 към масива, получаваме следната картина:

Добавяне на елемент към ArrayList 2

Сега масивът съхранява елемента 5 и size == 1.

Ако някой извика size()метода на нашия ArrayListобект сега, върнатата стойност ще бъде броя на елементите, съхранени в списъка: 1. Броят на елементите в списъка не е същият като капацитета за съхранение на масива.

Нито текущият капацитет за съхранение, нито самият масив някога ще бъдат достъпни (видими) извън обекта ArrayList. Това са и винаги ще бъдат ArrayListвътрешните данни на .

Нека добавим още 7 числа към списъка: 10, 20, 30, 40, 50, 60, 70.

Сега паметта ще изглежда така:

Добавяне на елемент към ArrayList

Ако извикате size()метода сега, той ще върне числото 8, което е новият брой елементи в списъка. Тази стойност няма нищо общо с размера на вътрешния масив.

Важно:

В тази картина има едно прекалено опростяване.

Класът ArrayListне може да съхранява примитивни типове, така че използва Integerтипа instead of int. Контейнерът не съхранява директно стойностите {5, 10, 20, 30, 40, 50, 60, 70}, а по-скоро препратки към Integerобекти. Всички празни клетки в контейнера се съхраняват null.



3. Увеличаване на дължината на списък

Нека да разгледаме Howво се случва в списъка, когато няма повече празни клетки във вътрешния му масив.

Да предположим, че имаме списък от 10 елемента:

Увеличаване на дължината на списък

Решаваме да добавим към него числото 100 . Ето Howво се случва в add()метода:

Стъпка 1 — Създайте нов масив:

Увеличаване на дължината на списък 2

Стъпка 2 — Копирайте всички елементи от стария масив в новия:

Увеличаване на дължината на списък 2

Стъпка 3 — Заменете стария масив (променете препратката към ArrayListвътрешния масив на обекта):

Увеличаване на дължината на списък 3

Стъпка 4 — Добавяне на новото число, което работихме толкова усилено, за да постигнем:

Увеличаване на дължината на списък 4