Бесплатный открытый урок: массивы фиксированной длины, списки ArrayList, словари HashMap и выход за границу индекса. Примеры проверены на JDK 21.
Массив: длина задаётся один раз
Массив хранит заданное число элементов одного типа. Индексы начинаются с нуля, поэтому последний элемент имеет номер length − 1. Длина — это поле length, а не метод.
import java.util.Arrays;
public class Massivy {
public static void main(String[] args) {
int[] ocenki = {5, 3, 4, 5, 2};
System.out.println("Всего оценок: " + ocenki.length);
System.out.println("Первая: " + ocenki[0]);
System.out.println("Последняя: " + ocenki[ocenki.length - 1]);
int summa = 0;
for (int ocenka : ocenki) {
summa += ocenka;
}
System.out.println("Сумма: " + summa);
System.out.println("Среднее: " + (double) summa / ocenki.length);
Arrays.sort(ocenki);
System.out.println(Arrays.toString(ocenki));
}
}
Всего оценок: 5
Первая: 5
Последняя: 2
Сумма: 19
Среднее: 3.8
[2, 3, 4, 5, 5]
- Цикл
for (int ocenka : ocenki)читается как «для каждой оценки из массива». Он короче обычногоfor, но не даёт номера элемента и не позволяет менять массив по индексу. (double) summaнужен, чтобы деление не стало целочисленным: без приведения среднее было бы3. Это та же ловушка, что в уроке о типах данных.- Печатать массив напрямую бесполезно:
System.out.println(ocenki)выведет что-то вроде[I@2f92e0f4. Для читаемого вида естьArrays.toString. Arrays.sortсортирует массив на месте — исходный порядок теряется.
Выход за границу массива
Компилятор такую ошибку не поймает: индекс становится известен только во время работы. Программа падает с исключением:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 3 out of bounds for length 3
at Vyhod.main(Vyhod.java:4)
Сообщение читают справа налево: длина массива 3, значит допустимые индексы — 0, 1 и 2, а программа попросила третий. Последняя строка указывает файл и номер строки, где это произошло.
Список: длина меняется
Когда число элементов заранее неизвестно, берут ArrayList. В угловых скобках указывают тип элементов — так компилятор проверит, что в список не попадёт посторонний объект.
import java.util.ArrayList;
import java.util.List;
public class Spisok {
public static void main(String[] args) {
List<String> gruppa = new ArrayList<>();
gruppa.add("Анна");
gruppa.add("Борис");
gruppa.add("Вера");
System.out.println(gruppa);
System.out.println("Человек в группе: " + gruppa.size());
System.out.println("Второй: " + gruppa.get(1));
System.out.println("Есть Вера: " + gruppa.contains("Вера"));
gruppa.remove("Борис");
for (String imya : gruppa) {
System.out.println(imya);
}
}
}
[Анна, Борис, Вера]
Человек в группе: 3
Второй: Борис
Есть Вера: true
Анна
Вера
Слева от знака равенства стоит List — интерфейс, справа ArrayList — конкретная реализация. Так принято: переменная описывает, что нужно, а не как это устроено внутри.
Осторожно с удалением из списка чисел: remove(1) удалит элемент с индексом 1, а remove(Integer.valueOf(1)) — само значение 1. Для строк такой двусмысленности нет.
Словарь: пары «ключ — значение»
HashMap хранит значения по ключу и находит их за одно обращение, без перебора всего списка.
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;
public class Slovar {
public static void main(String[] args) {
Map<String, Integer> bally = new HashMap<>();
bally.put("Анна", 92);
bally.put("Борис", 78);
bally.put("Вера", 85);
System.out.println("Баллов у Анны: " + bally.get("Анна"));
System.out.println("Баллов у Гриши: " + bally.getOrDefault("Гриша", 0));
for (Map.Entry<String, Integer> zapis : new TreeMap<>(bally).entrySet()) {
System.out.println(zapis.getKey() + " — " + zapis.getValue());
}
}
}
Баллов у Анны: 92
Баллов у Гриши: 0
Анна — 92
Борис — 78
Вера — 85
Важно: порядок обхода HashMap не определён и может отличаться на другой машине или в другой версии Java. Поэтому в примере словарь перед печатью завёрнут в TreeMap, который всегда идёт по возрастанию ключа. Если бы мы обходили bally напрямую, три последние строки могли выйти в любом порядке.
get для отсутствующего ключа вернёт null, и попытка сравнить его с числом уронит программу. getOrDefault избавляет от этой проверки.
length, length() и size()
Три похожих способа узнать размер легко перепутать: у массива это поле length, у строки — метод length(), у списка — метод size(). Ошибка ловится ещё компилятором:
int[] ocenki = {5, 3, 4};
System.out.println(ocenki.length());
Ответ компилятора — cannot find symbol: method length().
Задание для самопроверки
- Найдите в массиве чисел максимум и его индекс, не пользуясь
Arrays.sort. - Соберите список из десяти чисел и удалите из него все нечётные. Проверьте, что размер списка изменился.
- Посчитайте, сколько раз каждое слово встречается в массиве строк. Используйте
HashMapиgetOrDefault, а печатайте результат по отсортированным ключам.
Что дальше
Предыдущий урок — циклы: for, while и do-while, следующий и последний в разделе — классы и объекты. Все бесплатные занятия собраны в разделе «Уроки Java».