Class ArrayList

Открыта

— А вот и я.

— Привет, Элли!

— Сегодня новая интересная тема! Сейчас я расскажу тебе о новом интересном классе — ArrayList.

— О, новый класс? Круто! И что он умеет делать?

— Начну с небольшой предыстории. Программистам очень не нравилось одно свойство массива – его размер нельзя изменять. Что делать, если нужно сохранить в массиве ещё три элемента, а свободное место только одно?

— Единственным решением проблемы нехватки места в массиве было создание массива очень большого размера, чтобы все элементы туда точно поместились. Но это часто приводило к нерациональному расходу памяти. Если чаще всего в массиве хранилось три элемента, но был хотя бы мизерный шанс, что там их будет 100, приходилось создавать массив на 100 элементов.

— И что же придумали программисты?

— Они написали класс ArrayList (списочный массив), который выполнял ту же работу, что и Array (массив), но мог изменять свой размер.

— Интересный ход. И как же они это сделали?

— Внутри каждого объекта типа ArrayList хранится обычный массив элементов. Когда ты считываешь элементы из ArrayList, он считывает их из своего внутреннего массива. Когда записываешь – записывает их во внутренний массив. Вот сравни:

Array ArrayList
Создание контейнера элементов
String[] list = new String[10];
ArrayList<String> list = new ArrayList<String>();
Получение количества элементов
int n = list.length;
int n = list.size();
Взятие элемента из массива/коллекции
String s = list[3];
String s = list.get(3);
Запись элемента в массив
list[3] = s;
list.set(3, s);

— И в чем же преимущество ArrayList? Как по мне, так код стал длиннее.

— Во-первых, ArrayList поддерживает несколько дополнительных действий, которые очень часто приходится делать программистам во время работы, и которых нет у массива. Например – вставка и удаление элементов из середины массива, и чтобы не оставалось дырок.

— Во-вторых, изменение размера: когда нужно записать во внутренний массив ещё один элемент, а свободного места там нет, то внутри ArrayList делается вот что:

а) создаётся ещё один массив, в полтора раза больше размера внутреннего массива, плюс один элемент.

б) все элементы из старого массива копируются в новый массив.

в) новый массив сохраняется во внутренней переменной объекта ArrayList, старый массив объявляется мусором (мы просто перестаём хранить на него ссылку).

Array ArrayList
Добавление элемента в конец массива
Невозможно выполнить данное действие
list.add(s);
Вставка элемента в середину массива
Невозможно выполнить данное действие
list.add(15, s);
Вставка элемента в начало массива
Невозможно выполнить данное действие
list.add(0, s);
Удаление элемента из массива
Можно стереть элемент с помощью list[3] = null. Но тогда останется «дыра» в массиве.
list.remove(3);
8
Задача
Java Syntax,  7 уровень,  5 лекция
Недоступна
Набираем код
Иногда думать не надо, строчить надо! Как ни парадоксально звучит, порой пальцы «запоминают» лучше, чем сознание. Вот почему во время обучения в секретном центре JavaRush вы иногда встречаете задания на набор кода. Набирая код, вы привыкаете к синтаксису и зарабатываете немного материи. А ещё — боретесь с ленью.

— А как работать с этим ArrayList’ом?

— А практически так же, как и с массивом. Вот смотри. Давай сравним работу с ArrayList с работой с массивом. Для примера решим такую задачу «ввести 10 строк с клавиатуры и вывести их на экран в обратном порядке» .

— Смотри:

Используем Array
public static void main(String[] args)
{
Reader r = new InputStreamReader(System.in);
BufferedReader reader = new BufferedReader(r);

//ввод строк с клавиатуры
String[] list = new String[10];
for (int i = 0; i < list.length; i++)
{
  String s = reader.readLine();
  list[i] = s;
}

//вывод содержимого массива на экран
for (int i = 0; i < list.length; i++)
{
  int j = list.length - i - 1;
  System.out.println( list[j] );
}
}
Используем ArrayList
public static void main(String[] args)
{
Reader r = new InputStreamReader(System.in);
BufferedReader reader = new BufferedReader(r);

//ввод строк с клавиатуры
ArrayList<String> list = new ArrayList<String>();
for (int i = 0; i < 10; i++)
{
  String s = reader.readLine();
  list.add(s);
}

//вывод содержимого коллекции на экран
for (int i = 0; i < list.size(); i++)
{
  int j = list.size() - i - 1;
  System.out.println( list.get(j) );
}
}

— Я раскрасила одним цветом эквивалентные действия в обеих колонках.

— С одной стороны все по-другому, с другой – все осталось тем же самым.

— Ага. Только мы теперь не используем квадратные скобочки при работе с Class ArrayList. Вместо них мы используем методы get, set и add.

— Да, я уже заметил. Но все равно очень похоже.

Комментарии (113)
  • популярные
  • новые
  • старые
Для того, чтобы оставить комментарий вы должны авторизоваться
mistex7 уровень, Пермь
вчера, 20:00
Элли, ты очень вовремя с ArrayList! Даже не представляешь как!
Сергей Novichok7 уровень, Москва
17 июня, 16:54
А что с Паскалем? Помню, это был главный геморрой с жестким ограничением по длине массивов
GigaMax12 уровень
27 апреля, 07:42
Всё понятно)
Самуил Олегович18 уровень, Киев
26 апреля, 14:27
В 11—й строке можно было бы и так вставлять элементы в лист массив — list.set(i, s); или я ошибаюсь? И аdd не надо.
GigaMax12 уровень
27 апреля, 07:16
Там нельзя использовать set, так как длина списочного массива ещё не задана и эта команда создаст ошибку
Самуил Олегович18 уровень, Киев
27 апреля, 10:01
выходит сетом можно пользоваться только уже в сформированном массиве?
GigaMax12 уровень
27 апреля, 19:44
я думаю, что можно и в пустом, но инициализированном с заданным количеством элементов, например:
ArrayList<String> line = new ArrayList<>(5);  // Тут можно будет использовать set
Самуил Олегович18 уровень, Киев
28 апреля, 10:10
Спасибо, за разбор.
Ihor9 уровень, Киев
8 мая, 09:38
Подскажите, почему new ArrayList<>(5) без new ArrayList<String>(5)???
GigaMax12 уровень
10 мая, 05:43
Мы можем указать один раз тип данных(полная запись не обязательна, компилятор это понимает), например: String, в типе переменной ArrayList при объявлении. Это было в лекциях: ArrayList<String> list = new ArrayList<>(); ArrayList<Integer> number = new ArrayList<>(); и т.д.
Ihor9 уровень, Киев
10 мая, 14:29
Спасибо)
Дмитрий20 уровень
1 апреля, 12:20
Не пойму в чем разница между записать элемент в массив (set) т добавить элемент в массив (add)
George20 уровень
1 апреля, 18:23
Ниже был ответ: Метод set просто меняет значение элемента по определенному индексу с одного на другое, а метод add вставляет новый элемент на определенный индекс. То есть в первом случае количество элементов остается тем же, а во втором - увеличивается на 1.
RustiG19 уровень, Москва
19 февраля, 13:37
а что это за <> скобки такие? они используются только в ArrayList для указания типа?
Владислав23 уровень, Москва
24 февраля, 08:17
В них указывается, объекты какого класса мы будем в него вкладывать. Вообще для любого класса-контейнера (ArrayList один из них) компилятору нужно знать, что будет внутри, поэтому придумали так указывать.
Hexronimo20 уровень
24 февраля, 09:25
В коллекциях еще (они позже будут изучаться).
RustiG19 уровень, Москва
25 февраля, 18:03
Спасибо
Dmitry19 уровень, Екатеринбург
9 февраля, 15:15
Массивами пользоваться не имеет смысла, если есть коллекции, такой вывод?
Hexronimo20 уровень
24 февраля, 09:37
В коллекции вы можете хранить толко объекты, т.е. ArrayList<Integer> но не ArrayList<int>, объекты занимают больше памяти чем примитивы (https://habr.com/en/post/134102/), так что нужно делать выбор в зависимости от задачи. По крайней мере мне так кажется :)
АртемGeek25 уровень, Москва
5 апреля, 14:58
Добавлю также, Array хороши когда не знаешь точное кол-во элементов в массиве, потому что он расширяем.
воскресенье, 15:55
Спасибо за ссылку!
Arjuna9 уровень
19 января, 17:53
обьясните плз разницу между set(10,s) и add(10,s) - в обоих случаях добавляем элемент s в ячейку 10?
Богдан19 уровень, Киев
20 января, 00:48
Метод set просто меняет значение элемента по определенному индексу с одного на другое, а метод add вставляет новый элемент на определенный индекс. То есть в первом случае количество элементов остается тем же, а во втором - увеличивается на 1.
Михаил Кузьмин 22 уровень, Новосибирск
27 декабря 2018, 16:28
Как называется метод, проверяющий строку на содержание данного символа??
Veronika Nikitina17 уровень, Санкт-Петербург
30 декабря 2018, 20:48
Contains?
Artur41 уровень
25 декабря 2018, 10:10
Как же заморочно в java с массивами, в js это намного проще всё реализовано
AlexEremenko35 уровень
5 января, 08:55
Это ты еще Паскаль не видел ;)
Aliaksandr.Pitkevich13 уровень, Минск
21 января, 15:22
мой первый ЯП Javascript, Java для себя изучаю. Хоть в JS и по проще с массивами, но гибкости больше в джаве