Вітання! У попередніх лекціях ми детально розібрали таку структуру даних як масив і розглянули найпоширеніші приклади роботи з ними. Але ця структура даних має низку недоліків. Відповіддю на них у Java стала поява ArrayList. Якщо говорити максимально просто, то список ArrayList в Java - це "прокачаний" масив з великою кількістю нових можливостей.
Чим Java Arraylist відрізняється від звичайних масивів?
Взагалі, масиви - штука досить зручна і як ти вже помітив, з ними можна багато чого робити :) Тим не менш, масиви мають і ряд недоліків.- Обмежений розмір. Потрібно вже на етапі створення масиву знати, скільки осередків він має містити. Недооціниш потрібну кількість — місця не вистачить. Переоціниш - масив залишиться напівпорожнім, і це ще півбіди. Адже виходить, ти ще й виділиш під нього більший обсяг пам'яті, ніж потрібно.
- У масиву немає методів додавання елементів. Завжди доводиться явно вказувати індекс комірки, куди додати елемент. Якщо ненароком вказати вже зайняту комірку з якимось потрібним значенням, воно перезапишеться.
- Немає методів видалення елемента. Значення можна лише "обнулити".
public class Cat {
private String name;
public Cat(String name) {
this.name = name;
}
public static void main(String[] args) {
Cat[] cats = new Cat[3];
cats[0] = new Cat("Томас");
cats[1] = new Cat("Бегемот");
cats[2] = new Cat("Філіп Маркович");
cats[1] = null;
System.out.println(Arrays.toString(cats));
}
@Override
public String toString() {
return "Cat{" +
"name='" + name + '\'' +
'}';
}
}
Висновок:
[Cat{name='Томас'}, null, Cat{name='Фабопп Маркович'}] Всі ці недоліки можна усунути, використовуючи ArrayList. Створюється він дуже просто:
ArrayList<Cat> cats = new ArrayList<Cat>(); Тепер ми створили список для зберігання об'єктів Cat. Зверни увагу:ми не вказуємо розмір ArrayList'a, оскільки він автоматично розширюється. Як таке можливо? Легко. Ти здивуєшся, але в основі ArrayList'a лежить звичайнісінький масив :) Так, всередині у нього знаходиться масив, в якому зберігаються наші елементи. Але у ArrayList'a є спеціальний механізм роботи з ним:
- Коли цей внутрішній масив заповнюється, ArrayList створює в собі новий масив. Його розмір = (Розмір старого масиву * 1,5) +1.
- Всі дані копіюються зі старого масиву в новий
- Старий масив видаляється збирачем сміття.
add().
public static void main(String[] args) {
ArrayList<Cat> cats = new ArrayList<Cat>();
cats.add(new Cat("Бегемот"));
} Новий елемент додається до кінця списку. Тепер ризику переповнення немає, тому такий механізм є повністю безпечним. До речі, ArrayList вміє не тільки шукати об'єкт за індексом, а й навпаки – може знайти індекс об'єкта в ArrayList'і за посиланням на об'єкт! Для цього в ньому реалізований метод indexOf(): Ми передаємо в нього посилання на потрібний об'єкт, і indexOf()повертає нам його індекс:
public static void main(String[] args) {
ArrayList<Cat> cats = new ArrayList<>();
Cat thomas = new Cat("Томас");
Cat behemoth = new Cat("Бегемот");
Cat philipp = new Cat("Філіп Маркович");
Cat pushok = new Cat("Пушок");
cats.add(thomas);
cats.add(behemoth);
cats.add(philipp);
cats.add(pushok);
int thomasIndex = cats.indexOf(thomas);
System.out.println(thomasIndex);
} Висновок:
0 Все вірно, об'єкт thomasдійсно зберігається в комірці 0. У масивів є не лише недоліки, а й безперечні переваги. Один із них — пошук елемента за індексом. Оскільки ми вказуємо на індекс, тобто на конкретну адресау пам'яті, такий пошук у масиві здійснюється дуже швидко. ArrayList у Java теж так уміє! Для цього в ньому реалізовано метод get():
public static void main(String[] args) {
ArrayList<Cat> cats = new ArrayList<>();
Cat thomas = new Cat("Томас");
Cat behemoth = new Cat("Бегемот");
Cat philipp = new Cat("Філіп Маркович");
Cat pushok = new Cat("Пушок");
cats.add(thomas);
cats.add(behemoth);
cats.add(philipp);
cats.add(pushok);
Cat secondCat = cats.get(1);
System.out.println(secondCat);
} Висновок:
Cat{name='Бегемот'} Крім того, можна легко дізнатися, чи містить ArrayList якийсь конкретний об'єкт, чи ні. Це робиться за допомогою методу contains():
public static void main(String[] args) {
ArrayList<Cat> cats = new ArrayList<>();
Cat thomas = new Cat("Томас");
Cat behemoth = new Cat("Бегемот");
Cat philipp = new Cat("Філіп Маркович");
Cat pushok = new Cat("Пушок");
cats.add(thomas);
cats.add(behemoth);
cats.add(philipp);
cats.add(pushok);
cats.remove(pushok);
System.out.println(cats.contains(pushok));
}
Метод перевіряє, чи міститься елемент у внутрішньому масиві ArrayList'a, і повертає результат у вигляді boolean- trueабо false. Висновок:
false І ще важливе з приводу вставки. ArrayList дозволяє вставляти дані не тільки в кінець масиву, але і в будь-яку комірку за індексом. Для цього він має два методи:
add(int index, Cat element)set(int index, Cat element)
set()затирає старе значення, що зберігається в комірці. А вставка через add()спочатку зрушує всі елементи починаючи з [index]до кінця масиву, а в порожню комірку, що утворилася, додає потрібний тобі об'єкт. Ось приклад:
public static void main(String[] args) {
ArrayList<Cat> cats = new ArrayList<>();
Cat thomas = new Cat("Томас");
Cat behemoth = new Cat("Бегемот");
Cat philipp = new Cat("Філіп Маркович");
Cat pushok = new Cat("Пушок");
cats.add(thomas);
cats.add(behemoth);
System.out.
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ