Списки: List и ArrayList
Массив имеет фиксированную длину: создали на пять элементов — шестой не добавить. Список (List) растёт и сжимается сам. Это самая частая коллекция в Java-программах.
Создание списка
Самая распространённая реализация списка — ArrayList. Тип элементов указывают в угловых скобках: List<String> — список строк:
void main() {
List<String> names = new ArrayList<>();
names.add("Анна");
names.add("Олег");
IO.println(names);
IO.println(names.size());
}Результат:
[Анна, Олег]
2Справа достаточно пустых скобок <> — тип Java возьмёт из левой части. Метод size() возвращает количество элементов.
Чтение и замена
Элементы нумеруются с нуля, как в массиве. Метод get() читает элемент по индексу, а set() заменяет его:
void main() {
List<String> fruits = new ArrayList<>();
fruits.add("яблоко");
fruits.add("груша");
fruits.add("слива");
IO.println(fruits.get(0));
fruits.set(1, "персик");
IO.println(fruits);
}Результат:
яблоко
[яблоко, персик, слива]Вставка, удаление и поиск
add(индекс, элемент) вставляет элемент в середину и сдвигает остальные. remove() удаляет, contains() проверяет наличие, а indexOf() возвращает позицию или -1:
void main() {
List<String> tasks = new ArrayList<>();
tasks.add("купить хлеб");
tasks.add("позвонить маме");
tasks.add(0, "проснуться");
tasks.remove("купить хлеб");
IO.println(tasks);
IO.println(tasks.contains("проснуться"));
IO.println(tasks.indexOf("позвонить маме"));
}Результат:
[проснуться, позвонить маме]
true
1Неизменяемый список
List.of() создаёт список сразу с элементами. Такой список неизменяемый: добавить, удалить или заменить элемент нельзя. Это удобно для данных, которые не должны меняться:
void main() {
List<String> days = List.of("пн", "вт", "ср");
IO.println(days);
days.add("чт");
}Результат:
[пн, вт, ср]
Exception in thread "main" java.lang.UnsupportedOperationExceptionЕсли нужен изменяемый список с начальными данными, оберните его: new ArrayList<>(List.of("пн", "вт")).
Списки чисел
Коллекции хранят только объекты, поэтому вместо int пишут класс-обёртку Integer, вместо double — Double. Java сама превращает число в объект и обратно — это называется автоупаковкой:
void main() {
List<Integer> scores = new ArrayList<>(List.of(5, 3, 8));
int total = 0;
for (int score : scores) {
total += score;
}
IO.println("Сумма: " + total);
}Результат:
Сумма: 16Как устроены обёртки и почему их нельзя сравнивать через ==, разобрано в уроке классы-обёртки.
Частая ошибка
У списка два метода remove: remove(int index) удаляет по индексу, а remove(Object o) — по значению. Для списка Integer число в скобках считается индексом:
void main() {
List<Integer> numbers = new ArrayList<>(List.of(10, 20, 30));
numbers.remove(1);
IO.println(numbers);
numbers.remove(Integer.valueOf(10));
IO.println(numbers);
}Результат:
[10, 30]
[30]remove(1) удалил второй элемент, а не единицу. Чтобы удалить по значению, передайте объект: Integer.valueOf(10).