JavaRush /Курси /Java Syntax Zero /Робота з ArrayList

Робота з ArrayList

Java Syntax Zero
Рівень 13 , Лекція 4
Відкрита

1. Як влаштовано ArrayList

ArrayList — найпоширеніший клас у Java для зберігання елементів. Як же влаштовано цей ArayList і чому він так усім подобається?

Будова ArrayList проста й геніальна за своєю сутністю. Усередині кожного об'єкта ArrayList є два поля:

  • Масив зі списком елементів
  • Змінна size, яка зберігає кількість елементів списку

Усередині об'єкта ArrayList міститься звичайнісінький масив! Але не тільки. Там є ще змінна size, яка зберігає довжину списку. От як це працює.

Початкова довжина масиву всередині списку — 10 елементів. А змінна size дорівнює 0.

Якщо в список додати елемент, його буде збережено в 0-ву комірку масиву, а size збільшиться до 1.

Якщо додати ще один елемент, його буде збережено в 1-шу комірку, а size знову збільшиться на 1 і тепер дорівнюватиме двом.

Якщо при спробі додавання чергового елемента до списку в масиві вже немає місця, у методі add() відбувається от що:

  1. Створюється новий масив, у півтора раза довший за попередній.
  2. У нього копіюються всі елементи з наявного масиву.
  3. В об'єкті ArrayList замість старого масиву зберігається посилання на новий.
  4. В 11-ту комірку нового масиву записується переданий елемент.
  5. size збільшується на 1 і тепер дорівнюватиме 11.

Аналогічні дії відбуваються під час додавання (вставлення) елемента в середину списку. Наявні елементи зсуваються на 1 праворуч, і у вільну комірку масиву записується потрібний елемент.

Основні сценарії використання списку ми зараз розглянемо.


2. Додавання елемента до ArrayList

Розгляньмо, що відбувається всередині списку, коли до нього додають елементи. Одразу після створення об'єкта ArrayList ми маємо в пам'яті приблизно таку картину:

Маємо об'єкт типу ArrayList, усередині якого є два поля (дві змінні): масив (data) і кількість елементів (size). data зберігає посилання на контейнер (масив) із 10 елементів.

Якщо ми вирішимо додати в масив число 5, отримаємо таку картину:

У масиві тепер зберігається елемент 5, а змінна size == 1.

Якщо зараз викликати метод size() для нашого об'єкта ArrayList, отримаємо в результаті кількість елементів списку — 1. Кількість елементів списку — це не розмір масиву.

Ані справжній розмір масиву, ані сам масив ніколи не будуть доступні (їх не буде видно) поза об'єктом ArrayList. Це внутрішні дані ArrayList, і вони завжди ними залишаться.

Додаймо до списку ще 7 чисел: 10, 20, 30, 40, 50, 60, 70.

Наразі картина в пам'яті виявиться вже такою:

Якщо зараз викликати метод size(), він поверне число 8 — нову кількість елементів у списку. До розміру масиву воно не має жодного стосунку.

Важливо!

На цьому малюнку є одна неточність.

Клас ArrayList не може зберігати примітивні типи, тому замість типу int він використовує тип (клас-обгортку) Integer. Контейнер зберігає не значення 5–70, а посилання на об'єкти типу Integer. Усі порожні комірки контейнера зберігають null.



3. Збільшення довжини списку

Розгляньмо, що відбувається всередині списку, коли в його масиві закінчуються вільні комірки.

Припустімо, у нас був список із 10 елементів:

Ми вирішили додати до нього число 100. От що в цьому разі відбудеться в методі add():

Крок 1 — створення нового масиву:

Крок 2 — копіювання всіх елементів зі старого масиву в новий:

Крок 3 — заміна масиву (змінення посилання на масив усередині об'єкта ArrayList):

Крок 4 — додавання нового числа, заради чого ми так старалися:

Коментарі (8)
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ
Christopher Ward 595 Рівень 16
6 серпня 2024
Трошки скучно було через for вирішувати задачу, тому знайшов System.arraycopy(Object src, int srcIndex, Object dest, int destIndex, int length), де 1)src: Масив який копіюєм. 2)srcIndex: індекс з якого копіюємо в вихідному масиві 3)dest: Масив в який вставляємо 4)destIndex: індекс з якого вставляємо в новий масиві 5)length: кількість елементів які ми хочемо скопіювати в вихідному масиві.
Гаркін Рівень 14
21 травня 2024
А в завданні "Створюємо свій список" arrayList в нас вийшов хитрозробленою тваринкою, яка не є масивом (arrayList.length не спрацює, як і Arrays.toString(arrayList) ), і яка не є колекцією (тобто arrayList.size() також не спрацює). Ну і як дізнатись її розмір? (створити геттер для size. А ще геттер для capacity - цікаве число побачите.)
Natalya Рівень 16
25 жовтня 2024
Можна розмір виразити через capacity не використовуючи геттер
Пузирєй Денис Рівень 28
26 жовтня 2023
Цей Array.List, справді класна штука. Все настільки продумано. Круто
Yaroslav Tkachyk Рівень 23 Expert
6 січня 2023
Ще питання: "Створюється новий масив, у півтора раза довший за попередній." © В статтях описаний розмір нового внутрішнього масиву = (розмірСтарогоМасиву * 1.5) + 1 Де правда? :)
Roma Chernesh Рівень 16
22 січня 2023
Ото просто заплутано написано. Розмір нового масиву = (розмірСтарогоМасиву * 1.5) І це все. А про додавання + 1. Це вже йшлося про лічильник елементів у масиві. *тобто в нас є окремо "розмір масива" і "кількість елементів". Якщо цей момент незрозумілий, треба перечитати попередню статтю. По суті, ось усе, що пов'язано із розміром нового масиву (коли у старому закінчилося місце): Якщо при спробі додавання чергового елемента до списку в масиві вже немає місця, у методі add() відбувається от що: Створюється новий масив, у півтора раза довший за попередній ВСЕ
Yaroslav Tkachyk Рівень 23 Expert
4 січня 2023
Привіт! "В 11-ту комірку нового масиву записується переданий елемент..." © Питання: чому в 11-ту, а не в 10-ту? Був масив на 10 елементів з комірками 0,1,2,3,4,5,6,7,8,9 - які всі вже заповнені елементами; Створюється масив на 15 елементів з комірками 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14; Елементи зі старого масиву копіюються в новий масив; При додаванні наступного елементу - наступна вільна комірка (зі значенням за замовчуванням null) - це десята комірка в яку додається 11 елемент.
theylovevalera Рівень 51
22 лютого 2023
В лекції йдеться про порядок комірки у людському розумінні(відліку від 1),а не компіляторовому.11 комірка-це 11 комірка для нас,а для компілятора-вона 10)