Циклы, массивы и ввод данных
Формы циклов
while (condition) {
step();
}
do {
step();
} while (condition); // минимум одна итерация
for (int i = 0; i < limit; i++) {
step(i);
}
for (int value : values) {
consume(value);
}Enhanced for дает значение элемента, а не индекс. Для массива примитивов изменение переменной не меняет массив:
for (int value : values) {
value *= 2; // values не изменился
}Для записи нужен индекс. Для коллекций структурное изменение внутри enhanced loop обычно приводит к ConcurrentModificationException; используют Iterator.remove() или подходящий метод коллекции.
break, continue и метки
breakзавершает ближайший цикл;continueначинает следующую итерацию;- метка позволяет выйти из внешнего цикла, но часто отдельный метод с
returnчитается проще.
outer:
for (int row = 0; row < matrix.length; row++) {
for (int col = 0; col < matrix[row].length; col++) {
if (matrix[row][col] == target) break outer;
}
}Инвариант цикла
Для суммирования:
long sum = 0;
for (int i = 0; i < values.length; i++) {
sum += values[i];
}Перед итерацией i переменная sum равна сумме диапазона [0, i). Инвариант помогает проверить границы и отсутствие off-by-one.
Ввод массива
Scanner scanner = new Scanner(System.in);
int size = scanner.nextInt();
int[] values = new int[size];
for (int i = 0; i < values.length; i++) {
values[i] = scanner.nextInt();
}nextInt() не съедает перевод строки. Если после него вызвать nextLine(), сначала вернется остаток текущей строки:
int count = scanner.nextInt();
scanner.nextLine(); // дочитать конец строки
String title = scanner.nextLine();Для большого форматированного ввода BufferedReader и ручной разбор обычно быстрее Scanner. Закрытие Scanner закроет и System.in, поэтому в небольшом приложении нужно понимать, кто владеет входным потоком.
Рекурсивные обходы вынесены в Рекурсия.
На собеседовании
- Чем while отличается от do-while? Второй выполняет тело хотя бы раз.
- Можно ли enhanced for менять int[] через переменную value? Нет.
- Что делает continue? Пропускает остаток текущей итерации.
- Почему
nextLine()послеnextInt()бывает пустым? Остался перевод строки. - Как ловить off-by-one? Полуинтервалы и явный инвариант.